Struts2原理与程序开发
Struts是Apache软件基金会赞助的一个开源项目。Struts 2是Struts的升级产品。它旨在帮助程序员更方便的运用新的Model2模式来开发Java EE应用。
为了从根本上克服传统Java EE开发Model1(JSP+JavaBean)模式的缺陷,对其进行改造,发展出Model2模式。
Model2工作原理:其工作流程是按如下5个步骤进行的:
- Servlet接收浏览器发出的请求。
- Servlet根据不同的请求调用相应的JavaBean。
- JavaBean按自己的业务逻辑操作数据库。
- Servlet将结果传递给JSP视图。
- JSP将后台处理的结果呈现给浏览器。
JSP+Servlet+JavaBean的Model2模式虽然克服了Model1的缺陷,但它以重新引入原始Servlet编程为代价的。为了减少用Model2模式开发程序的代码工作量而发明了Struts 2。
Struts 2工作机制
Struts 2设计思想:用Se请求rvlet Filter(过滤器)技术将Servlet API隐藏于框架之内,一个在Struts 2框架内被处理,大致分为以下几个步骤:
- 客户端初始化一个指向Servlet容器如(Tomcat)的请求。
- 这个请求经过一系列的过滤器(Filter)(其中有一个叫做ActionContextCleanUp,它对于Struts 2和其他框架的集成很有帮助,如SiteMesh Plugin)。
- 接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请求是否需要调用某个Action。
- 如果ActionMapper觉得需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy。
- ActionProxy通过Configuration Manager询问框架的配置文件,找到需要调用的Action类。
- ActionProxy创建一个ActionInvoication的实例。
- ActionInvoication的实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Interceptor)的调用。
- 一旦Action执行完毕,ActionInvoication负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可能是另外的一个Action链)一个需要被表示的JSP或FreeMarker的模板。在表示的过程中可以使用Struts 2框架中继承的标签,在这个过程中还要涉及ActionMapper。
从Struts 2的内部机制可见,它实质上就是一个功能经过定制扩展的Servlet过滤器,只不过这个过滤器是专门设计来为简化Java EE开发服务的。
Struts 2框架的程序开发:
加载Struts 2包
登录http://struts.apache.org/,下载Struts 2完整版。将下载的压缩文件进行解压得到的文件目录结构如下图所示,它是一个典型的web结构。

apps:包含Struts 2的示例应用。
docs:包含Struts 2的相关文档,如包含Struts 2的快速入门Struts 2的API文档等内容。
lib:包含Struts 2框架的核心类库,以及Struts 2的第三方插件。
src:包含Struts 2框架的全部源代码。
常用到的几个类库:
commons-io-2.0.1.jar
commns-lang3-3.1.jar
commns-logging-1.1.1.jar:用于能够插入其它任何的日志系统。
commns-fileupload-1.2.2.jar
ognl-3.0.5.jar:OGNL表达式语言。
freemarker-2.3.19.jar:所有的UI标记模板。
javassist-3.11.0.GA.jar
struts2-core-2.3.4.1.jar: Struts 2框架类库
xwork-core-2.3.4.1.jar:Xwork项目,Struts 2就是再次基础上构建的。
mysql-cnnector-java-5.1.22-bin.jar
将上述常用的jar包(有时候需要的)复制到\WebRoot\WEB-INF\lib路径下。
在项目目录树中,右键单击选择菜单【Build Path】->【Configure Build Path...】->【Add External JARs...】完成Struts 2包的加载。
配置Struts 2
修改web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.FilterDispatcher
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<display-name>jsp_struts2_jdbc</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
可以发现:这其实就是在配置一个过滤器。
创建JavaBean
package org.easybooks.bookstore.jdbc; import java.sql.*; import javax.xml.transform.Result; public class MySQLConnBean { private Statement stmt = null; private Connection conn = null; ResultSet rs = null; // 构造函数 public MySQLConnBean() { } public void OpenConn() throws Exception { try { Class.forName("com.mysql.jdbc.Driver").newInstance(); String url = "jdbc:mysql://3306/test"; String user = "root"; String password = "mysql"; conn = DriverManager.getConnection(url, user, password); } catch (SQLException e) { System.out.println("Data.executeQuery:" + e.getMessage()); } } // 执行查询类的SQL语句 public ResultSet executeQuery(String sql) { rs = null; try { stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); rs = stmt.executeQuery(sql); } catch (SQLException e) { System.out.println("Data.executeQuery:" + e.getMessage()); } return rs; } // 关闭对象 public void closeStmt() { try { stmt.close(); } catch (SQLException e) { System.out.println("Data.executeQuery:" + e.getMessage()); } } public void closeConn() { try { conn.close(); } catch (SQLException e) { System.out.println("Data.executeQuery:" + e.getMessage()); } } }
创建需要的JSP文件
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 4 <html> 5 <head> 6 <title>登录页面</title> 7 </head> 8 <body> 9 <form action="login.action" method="post"> 10 用户登录<br> 11 姓名:<input type="text" name="username"><br> 12 密码:<input type="text" name="password"><br> 13 <input type="submit" value="登录"> 14 </form> 15 </body> 16 </html>
实现控制器Action
1 package org.easybooks.bookstore.action; 2 3 import java.sql.*; 4 import org.easybooks.bookstore.jdbc.MySQLConnBean; 5 import com.opensymphony.xwork2.ActionSupport; 6 //Action控制器 7 public class LoginAction extends ActionSupport { 8 private String username; 9 private String password; 10 11 // 处理用户请求的execute方法 12 public String execute() throws Exception { 13 String usr = getUsername(); 14 String pwd = getPassword(); 15 boolean validated = false; //验证成功标识 16 MySQLConnBean MysqlBean = new MySQLConnBean(); //创建连接对象 17 // 查询user表中的记录 18 String sql = "select * from user"; 19 MysqlBean.OpenConn(); //调用MysqlBean中加载JDBC驱方法 20 ResultSet rs = MysqlBean.executeQuery(sql); 21 while (rs.next()) { 22 if (rs.getString("username").compareTo(usr) == 0) { 23 validated = true; 24 } 25 } 26 rs.close(); 27 MysqlBean.closeStmt(); 28 MysqlBean.closeConn(); 29 if (validated) { 30 return "success"; 31 } else { // 验证失败返回字符串“error” 32 return "error"; 33 } 34 } 35 36 public String getUsername() { 37 return username; 38 } 39 40 public void setUsername(String username) { 41 this.username = username; 42 } 43 44 public void setPassword(String password) { 45 this.password = password; 46 } 47 48 public String getPassword() { 49 return password; 50 } 51 }
Struts 2改进了获取请求参数的方式,自动获取请求参数。
Struts 2获取请求参数的名称,拼成该参数的get和set方法,调用方法实现属性的存取操作。
配置Action
在编写好Action(控制器)的代码,还需要进行配置才能让Struts 2识别这个Action,在Src下创建文件struts.xml(注意文件位置和大小写),输入如下的代码:
1 <!DOCTYPE struts PUBLIC 2 "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" 3 "http://struts.apache.org/dtds/struts-2.0.dtd"> 4 <struts> 5 <constant name="struts.devMode" value="true" /> 6 <constant name="struts.locale" value="zh_CN" /> 7 <constant name="struts.i18n.encoding" value="gb2312" />A 8 9 <package name="struts" extends="struts-default"> 10 <action name="login" 11 class="org.easybooks.bookstore.action.LoginAction"> 12 <result name="success">/welcome.jsp</result> 13 <result name="error">/error.jsp</result> 14 </action> 15 </package> 16 </struts>
项目的目录结构如下图所示:

struts.properties文件
struts提供了很多可配置的属性,通过这些属性,可以改变框架的行为,从而满足不同web应用的需求。这些属性可以在struts.properties文件中进行设置,struts.properties是标准的Java属性文件格式,“#”号作为注释符号,文件内容由键(key)-值(value)对组成。
struts.properties文件必须位于classpath下,通常放在web应用程序的src目录下。
Struts 2在default.properties文件(位于struts2-core-2.3.4.1.jar\org\apache\struts2下)中给出了所以属性的列表,并对其中一些预置了默认值。如果开发人员创建了default.properties,那么文件中的属性设置会覆盖default.properties文件中的属性设置。
浙公网安备 33010602011771号