Struts2框架学习第三章——Struts2基础

本章要点

—  Struts 1框架的基本知识

— 使用Struts 1框架开发Web应用

—  WebWork框架的基本知识

— 使用WebWork框架开发Web应用

— 在Eclipse中整合Tomcat

— 使用Eclipse开发Web应用

— 为Web应用增加Struts 2支持

—  Struts 2框架的MVC组件

—  Struts 2框架的流程

— 通过web.xml文件加载Struts 2框架

— 通过struts.properties文件配置Struts 2属性

—  struts.xml文件的结构

— 前面一章已经大致介绍了Struts 2应用的基本情况,通过前一章的学习,读者应该对Struts 2框架有了一个大致的掌握。但对于各知识点的细节,还需要进一步学习,本章将详细介绍Struts 2框架的基础部分。

因为Struts 2是在WebWork和Struts 1的基础上发展起来的,因此掌握一定的WebWork和Struts 1框架的知识,将对于掌握Struts 2框架大有裨益。特别是WebWork方面的开发经验,绝大部分都可以适用于Struts 2应用的开发。本章将会简要介绍Struts 1和WebWork框架的使用。

本章还将介绍在Eclipse IDE工具中开发Struts 2应用,并且详细介绍Struts 2配置文件的各个细节。

3.1  Struts 1MVC实现

Struts 1是世界上最“古老”的MVC框架,它出现于2001年。Struts 1以ActionServlet作为核心控制器,由ActionServlet负责拦截用户的所有请求。Struts 1框架有3个重要组成部分:Action、ActionForm和ActionForward对象。

3.1.1  下载和安装Struts 1框架

本节的示例程序基于Struts 1的1.2.9版,请读者也下载该版本的Struts 1框架,下载和安装Struts 1框架请按如下步骤进行。

 登录struts.apache.org站点,下载Struts的合适版本。解压缩下载到的压缩包,解压缩后,发现有如下文件结构:

—  contrib:该路径下存放了Struts 1表达式语言支持的类库和标签库文件。

—  lib:该路径下存放了Struts 1框架的核心类库。

—  webapps:该路径下存放了Struts 1框架的示例应用及文档应用。

— 另外还一些关于Struts的说明和LICENSE等文档

 将lib下的JAR文件全部复制到WEB-INF/lib下,并将TLD文件全部复制到WEB-INF下,再将validator-rules.xml文件也复制到WEB-INF下。如果需要用到Struts-EL(表达式)语言,还应将contrib下的JAR文件复制到WEB-INF/lib下。

 为了在编译程序时可以导入Struts 1类库,还应将struts.jar文件增加到环境变量中。

3.1.2  实现ActionForm

Struts 1使用单独的ActionForm封装请求参数,当用户提交一个请求时,Struts 1将使用单独的ActionForm来封装所有的请求参数。从结构上看,ActionForm就是一个POJO:它需要为用户的每个请求参数都提供一个对应的属性,并为该属性设置相应的setter和getter方法——但ActionForm的设计不是POJO,它必须继承Struts 1的ActionForm基类。

下面是一个简单的登录页面,包含两个表单域,分别代表用户名和密码。该登录页面的代码如下:

<%@ page language="java" contentType="text/html;charset=gb2312" errorPage=""%>

<!--  导入Struts的三个标签库-->

<%@include file="taglibs.jsp"%>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=gb2312">

<!--  使用国际化资源文件的key输出标题-->

<title><bean:message key="login"/></title>

</head>

<body>

<!-- 输出登录页面标题 -->

<h3><bean:message key="loginTitle"/></h3>

<!-- 输出Action处理完后的错误信息。 -->

<font color="red">${requestScope.err}</font>

<!-- 通过messagePresent判断输入校验后的出错提示是否存在 -->

<logic:messagesPresent>

<!-- 输出出错提示 -->

<bean:message key="errors.header"/>

<ul>

<html:messages id="error">

<li><bean:write name="error"/></li>

</html:messages>

</ul><hr />

</logic:messagesPresent>

<!-- 下面是登录表单 -->

<html:form action="login.do">

<!-- 使用国际化信息来输出标签 -->

<bean:message key="username"/><html:text property="username"/><br>

<bean:message key="pass"/><html:password property="pass"/><br>

<html:submit><bean:message key="login"/></html:submit><br>

</html:form>

</body>

</html>

在浏览器中浏览该页面时,看到该页面包含了一个简单的登录表单。该页面的界面如图3.1所示。

该页面中有两个表单域,这两个表单域封装了需要向服务器发送的请求参数,对于Strurts应用而言,请求参数是通过ActionForm来封装的,ActionForm非常类似一个POJO(定义几个属性,为每个属性提供setter和getter方法),但该ActionFrom需要继承ActionForm,或者是它的子类。因为本应用使用了Struts的校验框架,因此本应用中的ActionForm继承了ValidatorForm类。下面是本应用中ActionForm类的代码:

public class LoginForm extends ValidatorForm

{

//下面两个属性用于封装两个表单域的请求参数

private String username;

private String pass;

//以下是属性字段的系列get、set方法

public String getUsername()

{

return username;

}

public void setUsername(String username)

{

this.username = username;

}

public String getPass()

{

return pass;

}

public void setPass(String pass)

{

this.pass = pass;

}

}

上面ActionForm类的代码非常简单,除了该类需要继承ValidatorForm之外。也正是因为该ActionForm继承了ValidatorForm,从而导致了该类的污染,降低了该类的代码复用。

对于Struts 1而言,ActionForm类是一个既烦琐又没有技术含量的类,写起来难免让程序员觉得意兴索然。虽然有很多IDE(集成开发环境)可以自动生成该ActionForm类,但Struts 1框架也感觉到大量重复书写该类是一个负担,后来提供了动态ActionForm,让人可以避免书写ActionForm类。

 注意  Struts 1中的ActionForm类是一个非常简单的类,它实质上是一个普通的JavaBean,但必须继承ActionForm类。除此之外,ActionForm还可以使用动态FormBean,从而允许通过配置文件来定义ActionForm。

3.1.3  实现Action

Action就是用于处理用户请求的业务控制器,当用户请求发送到ActionServlet后,ActionServlet拦截到用户请求,将请求转发到系统的业务控制器处理。ActionServlet在转发用户请求时,会将请求参数封装成ActionForm实例,并将该 ActionForm实例转发给Action实例。

Action实例从ActionForm中取出用户请求参数,然后调用业务逻辑组件处理用户请求,并根据处理结果,调用不同的视图页面来呈现处理结果。

下面是系统的Action处理类代码。

public class LoginAction extends Action

{

//必须重写该execute方法,该方法用于处理用户请求

public ActionForward execute(ActionMapping mapping, ActionForm form,

HttpServletRequest request, HttpServletResponse response)throws

Exception

{

//获取封装用户请求参数的ActionForm实例

LoginForm loginForm = (LoginForm)form;

//从ActionForm中取出用户请求参数

String username = loginForm.getUsername();

String pass = loginForm.getPass();

//处理用户请求

if (username != null && username.equals("scott"))

{

return mapping.findForward("welcome");

}

else

{

return mapping.findForward("error");

}

}

}

上面的Action代码非常简单,甚至没有调用任何业务逻辑组件,只是直接判断用户请求参数的用户名和密码是否为scott和tiger,如果用户名和密码正确,则返回welcome的ActionForward,否则返回error的ActionForward。

 注意  ActionForward就是一个逻辑视图,通过在配置文件中定义ActionFoward的映射,完成逻辑视图名和实际视图资源之间的映射。

Struts 1的Action类与Struts 2的Action类有一定的类似性,都通过调用execute方法来处理用户请求。但最大的区别在于Struts 1 Action的execute方法与Servlet API耦合,但Struts 2 Action类的execute方法无需与Servlet API耦合。

3.1.4  配置Struts 1Action

实现了Struts 1的Action后,还需要在struts-config.xml文件中配置Action,配置Action需要指定Action的实现类,以及Action处理请求的URL。

配置Action时,还应该配置该Action对应的ActionForm,每个ActionForm使用一个<form-bean.../>元素定义。定义Action和ActonForm之间的关联关系时,在定义Action的<action../>元素中通过name属性指定与此Action关联的ActionForm。

因为本应用还使用了Struts 1的数据校验框架,因此配置<action.../>元素时,还应该增加validate属性,并将该属性值设置成true;还需要增加input属性,该属性指向输入校验失败后转入的视图资源。

下面是本应用的struts-config.xml文件代码。

<?xml version="1.0" encoding="GBK"?>

<!-- 指定Struts 1配置文件的DTD信息 -->

<!DOCTYPE struts-config PUBLIC

"-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"

"http://struts.apache.org/dtds/struts-config_1_2.dtd">

<!-- 指定Struts 1配置文件的根元素 -->

<struts-config>

<!-- 所有的ActionForm都应该在form-beans元素中定义 -->

<form-beans>

<!-- 每个form-bean定义一个ActionForm -->

<form-bean name="loginForm" type="lee.LoginForm"/>

</form-beans>

<!-- 所有的Action都放在action-mappings元素中定义 -->

<action-mappings>

<!-- 定义Action,其处理类为lee.LoginAction,对应的ActionForm为

loginForm -->

<action path="/login" type="lee.LoginAction" name="loginForm"

validate="true" scope="request" input="/login.jsp">

<!-- 当返回welcome的ActionForward时,转入welcome.jsp页 -->

<forward name="welcome" path="/welcome.jsp" />

<!-- 当返回error的ActionForward时,转入error.jsp页 -->

<forward name="error" path="/error.jsp"/>

</action>

</action-mappings>

<!-- 加载国际化资源文件 -->

<message-resources parameter="MyResource"/>

<!-- 加载Struts 1校验框架的插件 -->

<plug-in className="org.apache.struts.validator.ValidatorPlugIn">

<!-- 指定数据校验的两个校验规则文件 -->

<set-property property="pathnames" value="/WEB-INF/validator-rules.xml,

/WEB-INF/validation.xml" />

<set-property property="stopOnFirstError" value="true"/>

</plug-in>

</struts-config>

正如前面看到的,页面中使用大量国际化标签来输出国际化消息,因此本应用必须加载相应的国际化资源文件,本应用的国际化资源文件的baseName是MyResource。指定应用的国际化资源文件通过<message-resources .../>元素指定。

本应用使用了Struts 1的校验框架来完成输入校验,因此在本应用中加载了两个校验规则文件,其中validator-rules.xml文件是一个系统规则文件,通常无需修改;validation.xml文件是开发者定义的规则文件,该文件定义了需要校验的表单应该满足的规则。

下面是校验规则文件的代码。

<?xml version="1.0" encoding="GBK"?>

<!-- 校验规则定义文件 -->

<!DOCTYPE form-validation PUBLIC "-//Apache Software Foundation

//DTD Commons Validator Rules Configuration 1.1.3//EN"

"http://jakarta.apache.org/commons/dtds/validator_1_1_3.dtd">

<!-- 校验规则文件的根元素 -->

<form-validation>

<formset>

<!-- 定义需要校验的ActionForm,定义该ActionForm为loginForm -->

<form name="loginForm">

<!-- 定义username表单域必须满足必填、模式匹配两个规则 -->

<field property="username" depends="required,mask">

<arg key="username" position="0"/>

<!-- 指定模式匹配在正则表达式 -->

<var>

<var-name>mask</var-name>

<var-value>^\w+$</var-value>

</var>

</field>

<!-- 定义pass表单域必须满足必填、最小长度两个规则 -->

<field property="pass" depends="required,minlength">

<arg key="pass" position="0"/>

<!-- 定义最小长度的规则 -->

<arg name="minlength" key="${var:minlength}" resource="false"

position="1"/>

<var>

<var-name>minlength</var-name>

<var-value>4</var-value>

</var>

</field>

</form>

</formset>

</form-validation>

上面的规则文件定义了表单域的两个表单必须满足的规则:username是必填的,而且必须匹配^\w+$的正则表达式;pass是必填的,并且至少有4位。

定义了上面的校验规则后,如果用户的输入不能通过该输入校验,则系统自动转入配置<action .../>元素时指定的input属性所对应的视图资源。

输入校验的提示信息都保存在国际化资源文件中,因此使用输入校验时,通常都建议使用国际化资源文件来保存校验提示信息。

 提示  使用输入校验时,通常建议使用国际化资源文件来保存校验失败的提示信息。

3.1.5  完成应用流程

经过上面步骤,可以非常清楚地看出上面示例应用的流程,用户进入系统的login.jsp页面,用户输入请求信息,发送请求。如果用户的请求参数不能通过输入校验,则系统将请求转发到login.jsp页面,否则请求将被转发到业务逻辑控制器Action处。

Action处理用户请求参数,如果处理结果为success的ActionForward,则进入welcome.jsp页面;如果处理结果为error的ActionForward,则进入error.jsp页面。

图3.2显示了该应用的顺序图。

图3.2  系统顺序图

如果用户输入的用户名正确、密码正确,用户登录成功,可以在welcome.jsp页面见到国际化的欢迎信息,并且通过Struts 1的标签输出登录的用户名。下面是welcome.jsp页面的代码。

<%@ page contentType="text/html;charset=gb2312" errorPage="error.jsp"%>

<!--  导入Struts的三个标签库-->

<%@include file="taglibs.jsp"%>

<html>

<head>

<!-- 通过Struts 1标签输出国际化的页面标题 -->

<title><bean:message key="loginSuccess"/></title>

</head>

<body>

<h3><bean:message key="loginSuccess"/></h3>

<hr>

<!-- 通过Struts 1标签输出国际化的欢迎信息,并把登录用的用户名作为参数传入 -->

<bean:message key="welcome" arg0="${loginForm.username}"/>

</body>

</html>

如果用户登录成功,将看到如图3.3所示的页面。

图3.3  登录成功页面

上面的Struts 1应用已经包含了Struts 1框架的核心部分,如ActionForm、Action实现,数据校验完成,应用的国际化支持等。

通过上面的示例应用,我们看到Struts 1框架的最大缺点是:Struts 1应用的类与Servlet API耦合严重,而且大都需要继承Struts 1框架提供的基类,或实现Struts 1框架提供的接口,造成了代码污染。

3.2  WebWorkMVC实现

WebWork由OpenSymphony组织负责开发、维护,WebWork 2前身是Rickard Oberg开发的WebWork。现在我们所说的WebWork,通常指的是WebWork 2,它是由Xwork 1和WebWork 2两个项目组成的。

WebWork紧紧以ServletDispatcher为核心,使用ServletDispatcher来处理所有的用户请求,它是整个WebWork框架的核心控制器。WebWork支持多视图表示,视图部分可以使用JSP、Velocity、FreeMarker、JasperReports、XML等。WebWork当前的最新版本是2.2.5,本节所使用的范例是基于该版本的WebWork完成的。由于WebWork已经全面整合到Struts 2框架中,故WebWork不会再有新版本发布,即不会有WebWork 2.3.X发布。

3.2.1  WebWork的下载和安装

WebWork当前的最新稳定版本是2.2.5,笔者建议读者也下载该版本。WebWork的下载和安装按如下步骤进行。

 登录http://www.opensymphony.com/webwork/站点,下载WebWork的最新稳定版,解压缩后发现如下的文件结构:

—  dist:该路径下存放了WebWork的两个编译版本。

—  docs:该路径下存放了WebWork的各种文档,包括WebWork的Wiki文档、API文档等。

—  lib:该路径下存放了WebWork编译和运行所需的第三方类库,其中default路径下的所有JAR文件是WebWork应用必需的类库文件。

—  src:该路径下存放了WebWork的源文件,如果使用WebWork过程中遇到无法解决的问题,可以参考该源文件解决。

—  webapps:该路径下存放了WebWork的示例应用,这些示例应用是学习WebWork极好的资料。

—  webwork-2.2.5.jar:该文件是WebWork框架的核心类库文件。

—  webwork-src-2.2.5.jar:该压缩文件里包含了WebWork框架所有源代码。

—  此外还有一些WebWork框架的编译脚本文件及各种说明文件。

WebWork通常都作为Web框架使用,在Web应用中使用该框架。为Web应用增加WebWork框架的方法,与在Web应用中增加其他框架的方法完全一样。下面介绍如何安装WebWork框架。

 将webwork-2.2.5.jar文件复制到Web应用的WEB-INF/lib路径下,再将lib\default路径下的*.jar文件全部复制到WEB-INF/lib下。

 注意  使用WebWork框架必须有webwork-2.2.5.jar和lib\default路径下的全部JAR文件。至于lib路径下的其他JAR文件,则是可选的——只有当应用中需要使用这些第三方框架时,才需要这些类库文件。

 为了可以编译WebWork应用程序,建议将webwork-2.2.5.jar增加到CLASSPATH的环境变量中。当然也可以使用Ant工具,则无需增加环境变量。

3.2.2  实现Action

用户需要实现的WebWork核心组件依然是业务控制器,业务控制器就是一个Action,该Action也包含一个execute方法,但该方法不再包含任何Servlet API,也不包含任何WebWork API。这个Action与Struts 1的Action不同,它非常类似于一个普通的POJO。

本应用的Action代码如下:

public class LoginAction extends ActionSupport

{

//下面两个属性用于封装用户请求参数

private String user;

private String pass;

//如下请求参数用于封装Action处理请求后的反馈

private String tip;

//user属性对应的setter和getter方法

public String getUser()

{

return user;

}

public void setUser(String user)

{

this.user = user;

}

//pass属性对应的setter和getter方法

public String getPass()

{

return pass;

}

public void setPass(String pass)

{

this.pass = pass;

}

//tip属性对应的setter和getter方法

public String getTip()

{

return tip;

}

//tip属性对应的setter和getter方法

public void setTip(String tip)

{

this.tip = tip;

}

//处理用户请求的execute方法

public String execute() throws Exception

{

if (getUser().equals("scott")

&& getPass().equals("tiger"))

{

setTip(getText("loginSuccess"));

return SUCCESS;

}

else

{

setTip(getText("loginFail"));

return ERROR;

}

}

}

上面Action类的代码与Struts 1的Action类存在如下几个区别:

—  WebWork的Action类无需与Servlet API耦合,从而可以更方便地进行单元测试。

—  WebWork的Action类可无需ActionForm的支持,它本身包含了两个属性用于封装用户的请求参数。

—  WebWork的Action类里包含的属性不仅可以封装用户请求参数,还可以封装Action的处理结果。

—  WebWork的Action的execute方法返回的逻辑视图是一个标准字符串,而不是一个ActionForward对象。

本应用中的Action继承了WebWork的ActionSupport基类,继承该基类导致了Action的代码污染,WebWork不强制要求Action类继承ActionSupport基类,但继承该基类可以更便捷地实现Action类,例如程序国际化。

上面的Action实现类中包含了两个国际化信息,这两个国际化信息对应的key分别为loginSuccess和loginFail。为了在Action类中访问这两个国际化信息,需要在Action类中使用getText方法,该方法可以输出对应key的国际化信息。该getText方法正是来自于ActionSupport基类的方法。

 注意  WebWork的Action类不强制要求使用ActionForm类封装用户请求参数。但可使用模型驱动模式,在模型驱动模式下,Action不再负责封装请求参数,也不负责封装Action的处理结果。而是将请求参数和处理结果放在模型中封装——模型就是一个类似于ActionForm的对象,但该对象是一个POJO,无需继承任何WebWork基类。相对于直接使用Action封装请求参数的模式,模型驱动模式的编程更加复杂,因为需要额外增加一个模型类;但模型驱动模式更易理解:Action专门负责处理用户请求,而模型则专门负责封装数据。

因为上面的Action封装了user和pass两个请求参数,故对应的JSP页面也应该包含这样两个表单域。下面是对应JSP页面的代码。

<%@ page contentType="text/html;charset=GBK"%>

<!-- 导入WebWork的标签库文件 -->

<%@ taglib prefix="ww" uri="/webwork"%>

<html>

<head>

<!-- 使用国际化信息标签输出国际化标题 -->

<title><ww:text name="loginTitle"/></title>

</head>

<body>

<ww:text name="loginTitle"/>

<hr>

<!-- 使用WebWork标签生成登录表单 -->

<ww:form method="post" action="login">

<!-- 生成登录用的用户名文本框 -->

<ww:textfield name="user" label="%{getText(‘user‘)}"/>

<!-- 生成登录用的密码文本框 -->

<ww:textfield name="pass" label="%{getText(‘pass‘)}"/>

<!-- 生成登录按钮 -->

<ww:submit value="%{getText(‘submit‘)}"/>

</ww:form>

</body>

</html>

读者可能已经注意到,上面的表单定义中,大量使用了WebWork的标签库,借助于WebWork标签库,可以更简单的生成页面的表单元素。因此,上面页面中的表单定义中,甚至无需为表单域指定对应的Label信息,但可生成如下表单定义。图3.4显示了在浏览器中浏览该页面的效果。

当使用<ww:textfield name="user" label="%{getText (‘user‘)}"/>来生成一个文本框时,该标签负责生成一个名为user的文本输入框,该输入框对应的Label通过%{getText(‘user‘)表达式生成输出,该表达式负责输出一个国际化信息,该国际化信息对应的key为user。

3.2.3  配置Action

实现上面的Action后,需要在应用中配置该Action。WebWork使用一个xwork.xml文件来配置Action。

在配置WebWork的Action之前,需要先配置Web应用加载WebWork框架。让Web应用加载WebWork框架就是配置WebWork的核心控制器,WebWork的核心控制器是ServletDispatcher。

因为Web应用默认只加载web.xml文件,因此为了加载WebWork框架,必须在web.xml文件中配置WebWork的核心控制器:ServletDispatcher。修改后的web.xml文件如下:

<?xml version="1.0" encoding="GBK"?>

<!-- 指定Web应用配置文件的Schema信息 -->

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.

com/xml/ns/j2ee/web-app_2_4.xsd"

version="2.4">

<!-- 配置WebWork的核心Servlet -->

<servlet>

<!-- 指定WebWork核心Servlet的名字 -->

<servlet-name>webwork</servlet-name>

<!-- 指定WebWork核心Servlet的实现类 -->

<servlet-class>com.opensymphony.webwork.dispatcher.ServletDispatcher

</servlet-class>

<load-on-startup>2</load-on-startup>

</servlet>

<!-- 配置WebWork核心Servlet的映射 -->

<servlet-mapping>

<!-- 配置WebWork核心Servlet映射的URL -->

<servlet-name>webwork</servlet-name>

<url-pattern>*.action</url-pattern>

</servlet-mapping>

</web-app>

指定了上面的web.xml配置文件后,Web应用会自动加载WebWork框架,并加载Web应用的WEB-INF/classes路径下的xwork.xml文件。xwork.xml文件就是WebWork的配置文件,该文件主要配置应用的Action,以及Action对应的URL。

<?xml version="1.0" encoding="GBK"?>

<!-- 下面指定了WebWork配置文件的DTD信息 -->

<!DOCTYPE xwork PUBLIC

"-//OpenSymphony Group//XWork 1.1//EN"

"http://www.opensymphony.com/xwork/xwork-1.1.dtd">

<!-- xwork是WebWork配置文件的根元素 -->

<xwork>

<!-- 导入WebWork默认配置文件 -->

<include file="webwork-default.xml" />

<!-- WebWork默认将Action配置放在package下管理 -->

<package name="default" extends="webwork-default">

<!-- 指定login的Action,该Action的实现类为lee.LoginAction -->

<action name="Login" class="lee.LoginAction">

<!-- 指定input逻辑视图对应的物理视图资源 -->

<result name="input">/login.jsp</result>

<!-- 指定error逻辑视图对应的物理视图资源 -->

<result name="error">/error.jsp</result>

<!-- 指定success逻辑视图对应的物理视图资源 -->

<result name="success">/success.jsp</result>

</action>

</package>

</xwork>

在上面的xwork.xml配置文件中,所有的Action放在package元素下管理,因为WebWork以包来管理所有的Action,所以全部的action元素都作为package元素的子元素存在。

 注意  WebWork以package来管理WebWork的Action,故所有的action元素都是package元素的子元素。

配置action元素时,必须指定两个主要属性:name属性和class属性。其中name属性指定了该Action负责处理的URL,而class属性指定了该Action对应的实现类。例如上面的Action配置,该Action的name为login,表示该Action负责处理向login.action的URL发送的请求,处理请求的Java类为lee.LoginAction。

实际上,WebWork可以包含两个配置文件,还有一个webwork.properties配置文件,这个文件是一个标准的属性文件,由一系列的WebWork属性的key和value组成。下面是webwork.properties文件的代码。

#指定该WebWork应用处于开发模式下,如果出错,将输出更多出错调试信息

webwork.devMode = true

#指定每次请求都重载WebWork的配置文件

webwork.configuration.xml.reload=true

#指定WebWork应用的国际化资源文件的baseName为mess

webwork.custom.i18n.resources=mess

因为本应用处于开发阶段,故设置了WebWork应用的开发模式为true,并且每次请求都会重载WebWork的配置文件。上面配置文件的最后一行指定了WebWork的国际化资源文件的baseName为mess。

上面配置WebWork应用时,指定了Action处理后逻辑视图名和物理视图之间的对应关系:"input"字符串对应/login.jsp页面,"error"字符串对应/error.jsp页面,"success"字符串对应/success.jsp页面。对比上面的Action类代码,发现该类的execute方法分别返回了SUCCESS和ERROR两个字符串常量——它们的定义包含在ActionSupport类中,其值分别为"success"和"error"字符串。

这就是本系统流程:当用户输入的用户名为scott,且密码为tiger时,Action返回一个success的逻辑视图,该逻辑视图对应为/success.jsp页面;否则将进入/error.jsp页面。那么input逻辑视图的作用呢?input逻辑视图是输入校验失败后默认转入的视图页面。

 提示  与Struts 1类似,WebWork采用input逻辑视图来作为输入校验失败后转入的视图。

3.2.4  完成数据校验

WebWork可以支持手动完成输入校验,但这不是本应用将采用的方式,因为手动完成输入校验需要重写Action类的validate()方法,需要大量书写重复代码,相当烦琐。本应用利用了XWork的校验框架来完成数据校验,完成数据校验只需要在Action class文件所在的路径下存放对应的校验文件即可。

下面是本应用的数据校验文件代码。

<?xml version="1.0" encoding="gb2312"?>

<!-- WebWork校验文件的DTD信息 -->

<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork

Validator 1.0.2//EN"

"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">

<!-- validators是校验文件的根元素 -->

<validators>

<!-- 使用表单校验器校验user表单域 -->

<field name="user">

<!-- 指定user表单域必须满足requiredstring(必填)规则 -->

<field-validator type="requiredstring">

<!-- 违反输入校验后的提示信息 -->

<message key="user.required"/>

</field-validator>

</field>

<!-- 使用表单校验器校验pass表单域 -->

<field name="pass">

<!-- 指定pass表单域必须满足requiredstring(必填)规则 -->

<field-validator type="requiredstring">

<message key="pass.required"/>

</field-validator>

<!-- 指定pass表单域必须满足stringlength(长度范围)规则 -->

<field-validator type="stringlength">

<!-- 指定最小长度 -->

<param name="minLength">3</param>

<!-- 指定最大长度 -->

<param name="maxLength">6</param>

<message key="pass.length"/>

</field-validator>

</field>

</validators>

上面的校验文件使用了两个表单校验器:requiredstring和stringlength,分别对应用的两个表单域进行校验,分别校验用户名必须满足必填规则,密码必须满足必填且字符串长度必须在3和6之间的规则。

如果用户输入不满足该规则,则看到如图3.5所示的界面。

图3.5  输入校验的效果

通过上面的示范代码,可以看出,结合XWork的校验框架,可以大大简化WebWork应用的数据校验。

对比上面的Struts 1框架和WebWork框架的使用,不难发现WebWork与Struts 2的设计更类似。

3.2.5  完成应用流程

正如我们见到的,如果我们输入了合适的用户名和密码,Action处理完用户请求后,将会封装一个名为tip的属性在结果里,并转入success的逻辑视图,该逻辑视图对应了/success.jsp页面。该页面的代码非常简单,它只是简单地使用WebWork标签来输出tip的提示信息。页面代码如下:

<%@ page contentType="text/html;charset=GBK"%>

<!-- 导入WebWork的标签库 -->

<%@ taglib prefix="ww" uri="/webwork"%>

<html>

<head>

<!-- 输出tip提示信息 -->

<title><ww:property value="tip"/></title>

</head>

<body>

<h3><ww:property value="tip"/></h3>

<!-- 使用WebWork的国际化标签来输出国际化提示 -->

<ww:text name="welcomeMsg">

<!-- 传入国际化提示信息的参数 -->

<ww:param value="user"/>

</ww:text>

</body>

</html>

在上面的页面中,我们使用了<ww.text .../>标签来输出国际化消息,该标签输出的国际化消息如下:

welcomeMsg=欢迎您,{0},您已经成功登录本系统!

看到上面的国际化消息需要传入一个参数,我们通过为<ww:text .../>标签指定一个<ww:param .../>子标签来传入参数:第一个<ww:param .../>子元素为第一个参数指定值,第二个<ww:param .../>子元素为第二个参数指定值……依此类推。

上面代码使用了<ww:param value="user"/>来传入参数,该参数的值就是Action中user属性值。当用户输入的用户名和密码正确时,将看到如图3.6所示的界面。

图3.6  登录成功的界面

3.3  Eclipse中开发Struts 2

前面已经详细介绍了如何开发一个Struts 2应用,但没有使用任何IDE工具,那种开发方式虽然能让读者更清楚开发的细节,但对于开发效率却不如使用IDE工具的开发效率高。本节将以Eclipse为例,介绍如何在IDE工具中开发Struts 2应用。

3.3.1  创建Web应用

笔者所使用的Eclipse已经安装了MyEclipse插件,因此可以很方便地建立一个Web应用,并将其部署在Web服务器中。

下面以Tomcat 5520为例,介绍如何在Eclipse中整合Tomcat服务器,新建一个Web应用,并将该应用部署到Tomcat服务器中。

现在开始在Eclipse中整合Tomcat服务器,实际上,如果我们安装了MyEclipse插件,则可以在Eclipse中整合大部分的Java EE服务器(包括Web服务器)。但如果我们没安装任何插件,Eclipse则很难与任何Java EE服务器整合。

 提示  Eclipse必须安装了相应插件后才具有丰富的功能。为了开发Java EE应用,通常都推荐安装MyEclipse插件,该插件是一个商业产品,必须支付相应费用才可使用。

为了在Eclipse中整合Tomcat服务器,请按如下步骤进行。

 单击Eclipse窗口里的“Window”菜单,在出现的“Window”的系列菜单项中选择“Preferences”菜单项,将弹出如图3.7所示的界面。

该Preferences设置窗口是Eclipse大部分参数的设置窗口,该窗口还可设置Eclipse插件的相关属性。MyEclipse插件的相关属性就是在该窗口里设置的,而整合Java EE服务器只是MyEclipse插件的相关属性。

 单击图3.7所示窗口左边导航树中的“MyEclipse”节点,然后单击“MyEclipse”节点下的“Application Servers”子节点,将看到如图3.8所示的界面。

图3.7  Eclipse的Preferences设置窗口

图3.8  在Eclipse中整合应用服务器

 拖动图3.8所示窗口左边的垂直滚动条,我们可以发现大部分应用服务器的名字,例如Jboss、Jetty、Resin等,当然也可以发现我们需要使用的Tomcat节点,然后单击Tomcat 5节点,出现如图3.9所示的界面。

图3.9  整合Tomcat5

 在图3.9右上方看到两个单选框:Enable和Disable,为了整合Tomcat,显然应该选中Enable单选框。选中该单选框后,还应该在下面的三个文本输入框内输入相应的地址,例如,Tomcat Home Directory里应该输入Tomcat的安装路径,笔者的Tomcat安装在D盘的tomcat5520路径下,故在该文本框内输入了D:\tomcat5520的内容。通常,一旦我们输入了正确的Tomcat安装路径,下面的两个文本框会自动输入,无需用户干预。

 单击图3.9所示窗口右下方的“OK”按钮,返回Eclipse主界面,Eclipse和Tomcat的整合成功。

下面介绍如何在Eclipse中建立一个Web应用,在Eclipse中建立一个Web应用也可借助于MyEclipse的帮助。借助于MyEclipse建立Web应用按如下步骤进行。

 单击Eclipse主界面中的“File”菜单,在出现的菜单中单击“New”下的“Other...”菜单项,将弹出一个如图3.10所示的对话框。

 在如图3.10所示的对话框中,选中“Web Project”节点,表明将要创建一个Web应用,然后单击“Next”按钮,看到如图3.11所示的对话框。

图3.10  新建Web应用的对话框                      图3.11  新建Web应用

 在如图3.11所示对话框的Project Name文本框中输入应用的名字,本应用使用Struts2Demo作为应用的名字,输入完成后可看到如图3.11所示的对话框。单击“Finish”按钮,新建Web应用成功。

3.3.2  增加Struts 2支持

为了让Web应用具有Struts 2支持功能,必须将Struts 2框架的核心类库增加到Web应用中。将Struts 2框架下lib路径下的struts2-core-2.0.6.jar、xwork-2.0.1.jar等Struts 2框架的核心类库复制到Web应用的lib路径下,也就是“%workspace%Struts2Demo\WebRoot\ WEB-INF\lib”路径下。

返回Eclipse的主界面,在Eclipse主界面的左上角资源导航中看到了struts2Demo节点,选中该节点,然后按F5键,将看到Eclipse主界面左上角资源导航中出现如图3.12所示的界面。

看到如图3.12所示的界面,表明该Web应用已经加入了Struts 2的核心类库,但还需要修改web.xml文件,让该文件负责加载Struts 2框架。

在如图3.12所示的导航树中,单击“WEB-INF”节点前的加号,展开该节点,看到该节点下包含的web.xml文件子节点。

单击web.xml文件节点,编辑该文件,编辑该文件没有丝毫特殊之处,同样是在web.xml文件中定义Struts 2的核心Filter,并定义该Filter所拦截的URL 模式。至此,该Web应用完全具备了Struts 2框架的支持。

3.3.3  部署Struts 2应用

本应用的功能非常类似于第2章所介绍的Struts 2应用,因此本节所使用的JSP页面与第2章所使用的JSP页面也非常类似,故此处不再给出这些JSP页面的代码。

在Eclipse中添加JSP页面也是很简单的,此处不再赘述。

建立了这些JSP页面后,单击Eclipse主界面上部署Web应用的工具按钮,部署Web应用和启动服务器的两个按钮如图3.13所示。

图3.13  在Eclipse中部署Web应用和启动服务器的按钮

在Eclipse中部署Web应用请按如下步骤进行。

 单击部署Web应用的按钮,弹出如图3.14所示的对话框。

图3.14  部署Web应用的对话框

 在图3.14所示对话框的上面看到选择项目的下拉列表,选中需要部署的Web应用,例如本示例就是Struts2Demo。单击右边的“Add”按钮,该按钮用于添加想要部署到的Web服务器,将看到如图3.15所示的对话框。

图3.15  部署到应用服务器

 在图3.15所示对话框上面的Server下拉列表中选中“Tomcat 5”选项,其他选项设置参照图3.15,然后单击“Finish”按钮,返回图3.14所示对话框,单击“OK”按钮,Web应用部署成功。

 Web应用部署成功后,单击如图3.13所示工具条中的“启动服务器”按钮旁的小三角,出现下拉菜单,选择“Tomcat 5”下的“Start”菜单项,如图3.16所示,启动Tomcat服务器。

在浏览器中访问刚才的Struts2Demo应用,将可看到本应用登录页面。以Tomcat的端口为8888为例,应该在浏览器中访问如下地址:http://localhost:8888/Struts2Demo/ login.jsp,将看到如图3.17所示的界面。

图3.16  启动服务器                         图3.17  部署成功后的登录界面

在图3.17中看到该登录页面的文本框没有任何提示信息,按钮上也没有文本,这是因为本应用缺少国际化资源文件。增加该应用所需的国际化资源文件,该资源文件与前面应用的资源文件相同,此处不再给出。

为了让Struts 2应用加载该国际化资源文件,还应该使用struts.properties文件,该文件内指定如下一行代码:

#指定Struts 2的国际化资源文件的baseName为messageResource

struts.custom.i18n.resources=messageResource

至此,Struts 2应用已经获得了国际化支持。如果在浏览器中再次浏览该页面,将看到如图3.18所示的界面。

3.3.4  增加应用的Action

在Eclipse工具中新建一个Java类,该Java类的类名为“LoginAction”,其代码与第2章所使用的LoginAction类代码相同,将该类文件保存在Struts2Demo应用的src路径下的lee目录下。

图3.18  增加了国际化资源文件后的登录页面

新建一个Java文件的方法非常简单,此处不再赘述。本应用的Action类的代码与第2章的Action类完全一样,此处也不再给出。

增加了Struts 2的Action类后,还需要增加对应的配置文件,也是通过单击Eclipse的“File”菜单,然后单击“New”下的“File”菜单项来操作的。

 提示  因为Eclipse暂时还没有专门的Struts 2插件,因此只能用最原始的方式来建立一个Struts 2的配置文件。等到专门的Struts 2插件被开发出来后,应该可以有更简单的方法来建立Struts 2的配置文件。

建立该文件后,为该文件增加Struts 2的Action定义,定义该Action与前面介绍的基本一致,需要定义Action的name属性、class属性等。增加Action定义后的struts.xml文件代码如下:

<?xml version="1.0" encoding="GBK"?>

<!-- 指定Struts 2配置文件的DTD信息 -->

<!DOCTYPE struts PUBLIC

"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

"http://struts.apache.org/dtds/struts-2.0.dtd">

<!-- 指定Struts 2配置文件的根元素 -->

<struts>

<!-- 所有的Action定义都应该放在package下 -->

<package name="lee" extends="struts-default">

<!-- 定义Action -->

<action name="Login" class="lee.LoginAction">

<!-- 定义三个逻辑视图和物理资源之间的映射 -->

<result name="input">/login.jsp</result>

<result name="error">/error.jsp</result>

<result name="success">/welcome.jsp</result>

</action>

</package>

</struts>

至此,整个Struts 2应用完全建立成功,如果读者还需要增加数据校验,则可增加对应的校验文件,并将该文件放在与对应Action源文件的同一路径下即可。

3.4  Struts 2的基本流程

经过前面介绍,我们已经基本了解了Struts 2框架的MVC实现。大致上,Struts 2框架由3个部分组成:核心控制器FilterDispatcher、业务控制器和用户实现的业务逻辑组件。在这3个部分里,Struts 2框架提供了核心控制器FilterDispatcher,而用户需要实现业务控制器和业务逻辑组件。

3.4.1  核心控制器:FilterDispatcher

FilterDispatcher是Struts 2框架的核心控制器,该控制器作为一个Filter运行在Web应用中,它负责拦截所有的用户请求,当用户请求到达时,该Filter会过滤用户请求。如果用户请求以action结尾,该请求将被转入Struts 2框架处理。

Struts 2框架获得了*.action请求后,将根据*.action请求的前面部分决定调用哪个业务逻辑组件,例如,对于login.action请求,Struts 2调用名为login的Action来处理该请求。

Struts 2应用中的Action都被定义在struts.xml文件中,在该文件中定义Action时,定义了该Action的name属性和class属性,其中name属性决定了该Action处理哪个用户请求,而class属性决定了该Action的实现类。

Struts 2用于处理用户请求的Action实例,并不是用户实现的业务控制器,而是Action代理——因为用户实现的业务控制器并没有与Servlet API耦合,显然无法处理用户请求。而Struts 2框架提供了系列拦截器,该系列拦截器负责将HttpServletRequest请求中的请求参数解析出来,传入到Action中,并回调Action的execute方法来处理用户请求。

显然,上面的处理过程是典型的AOP(面向切面编程)处理方式。图3.19显示了这种处理模型。

图3.19  Struts 2的拦截器和Action

从图3.19中可以看出,用户实现的Action类仅仅是Struts 2的Action代理的代理目标。用户实现的业务控制器(Action)则包含了对用户请求的处理。用户的请求数据包含在HttpServletRequest对象里,而用户的Action类无需访问HttpServletRequest对象。拦截器负责将HttpServletRequest里的请求数据解析出来,并传给业务逻辑组件Action实例。

3.4.2  业务控制器

正如从图3.19所看到的,业务控制器组件就是用户实现Action类的实例,Action类里通常包含了一个execute方法,该方法返回一个字符串——该字符串就是一个逻辑视图名,当业务控制器处理完用户请求后,根据处理结果不同,execute方法返回不同字符串   ——每个字符串对应一个视图名。

程序员开发出系统所需要的业务控制器后,还需要配置Struts 2的Action,即需要配置Action的如下三个部分定义:

—  Action所处理的URL。

—  Action组件所对应的实现类。

—  Action里包含的逻辑视图和物理资源之间的对应关系。

每个Action都要处理一个用户请求,而用户请求总是包含了指定URL。当Filter Dispatcher拦截到用户请求后,根据请求的URL和Action处理URL之间的对应关系来处理转发。

3.4.3  Struts 2的模型组件

实际上,模型组件已经超出了MVC框架的覆盖范围。对于Struts 2框架而言,通常没有为模型组件的实现提供太多的帮助。

Java EE应用里的模型组件,通常指系统的业务逻辑组件。而隐藏在系统的业务逻辑组件下面的,可能还包含了DAO、领域对象等组件。

通常,MVC框架里的业务控制器会调用模型组件的方法来处理用户请求。也就是说,业务逻辑控制器不会对用户请求进行任何实际处理,用户请求最终由模型组件负责处理。业务控制器只是中间负责调度的调度器,这也是称Action为控制器的原因。

图3.20显示了这种处理流程。

 提示  在图3.20中看到Action调用业务逻辑组件的方法。当控制器需要获得业务逻辑组件实例时,通常并不会直接获取业务逻辑组件实例,而是通过工厂模式来获得业务逻辑组件的实例;或者利用其他IoC容器(如Spring容器)来管理业务逻辑组件的实例。

3.4.4  Struts 2的视图组件

Struts 2已经改变了Struts 1只能使用JSP作为视图技术的现状,Struts 2允许使用其他的模板技术,如FreeMarker、Velocity作为视图技术。

当Struts 2的控制器返回逻辑视图名时,逻辑视图并未与任何的视图技术关联,仅仅是返回一个字符串,该字符串作为逻辑视图名。

当我们在struts.xml文件中配置Action时,不仅需要指定Action的name属性和class属性,还要为Action元素指定系列result子元素,每个result子元素定义一个逻辑视图和物理视图之间的映射。前面所介绍的应用都使用了JSP技术作为视图,故配置result子元素时没有指定type属性,默认使用JSP作为视图资源。

如果需要在Struts 2中使用其他视图技术,则可以在配置result子元素时,指定相应的type属性即可。例如,如果需要使用FreeMarker,则为result指定值为freemarker的type属性;如果想使用Velocity模板技术作为视图资源,则为result指定值为velocity的type属性……

3.4.5  Struts 2的运行流程

经过上面介绍,我们发现Struts 2框架的运行流程非常类似于WebWork框架的流程。

 提示  在Struts 2的官方站点,我们可以找到如下说法:Essentially,Struts 2.0 is the technical equivalent of WebWork 2.3。Aside from the package and property renaming,it isn‘t much different than,say,migrating from WebWork 2.1 to 2.2——意思是说:Struts 2.0技术等同于WebWork 2.3框架,除了包和属性被改名外。从WebWork 2.2迁移到Struts 2不会比从WebWork 2.1迁移到WebWork 2.2更复杂。

这里我们可以看到,Struts 2其实就是WebWork 2.2的升级版,这也就不难理解:为什么WebWork和Struts 2如此相似!

因此,Struts 2的运行流程与WebWork的运行流程完全相同,读者可以参看图1.8来了解Struts 2的运行流程。

3.5  Struts 2的基本配置

前面大致了解了Struts 2框架的基本内容,但这些基本内容都必须建立在Struts 2的配置文件基础之上,这些配置文件的配置信息也是Struts 2应用的核心部分。

3.5.1  配置web.xml文件

任何MVC框架都需要与Web应用整合,这就不得不借助于web.xml文件,只有配置在web.xml文件中Servlet才会被应用加载。

通常,所有的MVC框架都需要Web应用加载一个核心控制器,对于Struts 2框架而言,需要加载FilterDispatcher,只要Web应用负责加载FilterDispatcher,FilterDispatcher将会加载应用的Struts 2框架。

因为Struts 2将核心控制器设计成Filter,而不是一个普通Servlet。故为了让Web应用加载FilterDispacher,只需要在web.xml文件中配置FilterDispatcher即可。

配置FilterDispatcher的代码片段如下:

<!-- 配置Struts 2框架的核心Filter -->

<filter>

<!-- 配置Struts 2核心Filter的名字 -->

<filter-name>struts</filter-name>

<!-- 配置Struts 2核心Filter的实现类 -->

<filter-class>org.apache.struts2.dispatcher.FilterDispatcher

</filter-class>

<init-param>

<!-- 配置Struts 2框架默认加载的Action包结构 -->

<param-name>actionPackages</param-name>

<param-value>org.apache.struts2.showcase.person</param-value>

</init-param>

<!-- 配置Struts 2框架的配置提供者类 -->

<init-param>

<param-name>configProviders </param-name>

<param-value>lee.MyConfigurationProvider</param-value>

</init-param>

</filter>

正如上面看到的,当配置Struts 2的FilterDispatcher类时,可以指定一系列的初始化参数,为该Filter配置初始化参数时,其中有3个初始化参数有特殊意义:

—  config:该参数的值是一个以英文逗号(,)隔开的字符串,每个字符串都是一个XML配置文件的位置。Struts 2框架将自动加载该属性指定的系列配置文件。

—  actionPackages:该参数的值也是一个以英文逗号(,)隔开的字符串,每个字符串都是一个包空间,Struts 2框架将扫描这些包空间下的Action类。

—  configProviders:如果用户需要实现自己的ConfigurationProvider类,用户可以提供一个或多个实现了ConfigurationProvider接口的类,然后将这些类的类名设置成该属性的值,多个类名之间以英文逗号(,)隔开。

除此之外,还可在此处配置Struts 2常量,每个<init-param>元素配置一个Struts 2常量,其中<param-name>子元素指定了常量name,而<param-value>子元素指定了常量value。

 提示  关于Struts 2常量的讲解,请参阅本书的4.1.2节。

在web.xml文件中配置了该Filter,还需要配置该Filter拦截的URL。通常,我们让该Filter拦截所有的用户请求,因此使用通配符来配置该Filter拦截的URL。

下面是配置该Filter拦截URL的配置片段:

<!-- 配置Filter拦截的URL -->

<filter-mapping>

<!-- 配置Struts 2的核心FilterDispatcher拦截所有用户请求 -->

<filter-name>struts</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

配置了Struts 2的核心FilterDispatcher后,基本完成了Struts 2在web.xml文件中的配置。

如果Web应用使用了Servlet 2.3以前的规范,因为Web应用不会自动加载Struts 2框架的标签文件,因此必须在web.xml文件中配置加载Struts 2标签库。

配置加载Struts 2标签库的配置片段如下:

<!-- 手动配置Struts 2的标签库 -->

<taglib>

<!-- 配置Struts 2标签库的URI -->

<taglib-uri>/s</taglib-uri>

<!-- 指定Struts 2标签库定义文件的位置 -->

<taglib-location>/WEB-INF/struts-tags.tld</taglib-location>

</taglib>

在上面配置片段中,指定了Struts 2标签库配置文件物理位置:/WEB-INF/struts- tags.tld,因此我们必须手动复制Struts 2的标签库定义文件,将该文件放置在Web应用的WEB-INF路径下。

如果Web应用使用Servlet 2.4以上的规范,则无需在web.xml文件中配置标签库定义,因为Servlet 2.4规范会自动加载标签库定义文件。

 提示  Struts 2的标签库定义文件包含在struts2-core-2.0.6.jar文件里,在struts2-core-2.0.6.jar文件的META-INF路径下,包含了一个struts-tag.tld文件,这个文件就是Struts 2的标签库定义文件,Servlet 2.4规范会自动加载该标签库文件。

对于Servlet 2.4以上的规范,Web应用自动加载该标签库定义文件。加载struts-tag.tld标签库定义文件时,该文件的开始部分包含如下代码片段:

<taglib>

<!-- 定义标签库的版本 -->

<tlib-version>2.2.3</tlib-version>

<!-- 定义标签库所需的JSP版 -->

<jsp-version>1.2</jsp-version>

<short-name>s</short-name>

<!-- 定义Struts 2标签库的URI -->

<uri>/struts-tags</uri>

...

</taglib>

因为该文件中已经定义了该标签库的URI:struts-tags,这就避免了在web.xml文件中重新定义Struts 2标签库文件的URI。

3.5.2  struts.xml配置文件

Struts框架的核心配置文件就是struts.xml配置文件,该文件主要负责管理Struts 2框架的业务控制器Action。

在默认情况下,Struts 2框架将自动加载放在WEB-INF/classes路径下的struts.xml文件。在大部分应用里,随着应用规模的增加,系统中Action数量也大量增加,导致struts.xml配置文件变得非常臃肿。

为了避免struts.xml文件过于庞大、臃肿,提高struts.xml文件的可读性,我们可以将一个struts.xml配置文件分解成多个配置文件,然后在struts.xml文件中包含其他配置文件。

下面的struts.xml文件中就通过include手动导入了一个配置文件:struts-part1.xml文件,通过这种方式,就可以将Struts 2的Action按模块配置在多个配置文件中。

<?xml version="1.0" encoding="UTF-8" ?>

<!-- 指定Struts 2配置文件的DTD信息 -->

<!DOCTYPE struts PUBLIC

"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

"http://struts.apache.org/dtds/struts-2.0.dtd">

<!-- 下面是Struts 2配置文件的根元素 -->

<struts>

<!-- 通过include元素导入其他配置文件 -->

<include file="struts-part1.xml" />

...

</struts>

通过这种方式,Struts 2提供了一种模块化的方式来管理struts.xml配置文件。

除此之外,Struts 2还提供了一种插件式的方式来管理配置文件。用WinRAR等解压缩软件打开struts2-core-2.0.6.jar文件,看到如图3.21所示的文件结构,在光标选中的一行,看到有一个struts-default.xml文件。

图3.21  struts2-core-2.0.6.jar压缩文件的文件结构

查看struts-default.xml文件,看到该文件代码片段如下:

<?xml version="1.0" encoding="UTF-8" ?>

<!-- 指定Struts 2配置文件的DTD信息 -->

<!DOCTYPE struts PUBLIC

"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

"http://struts.apache.org/dtds/struts-2.0.dtd">

<!-- Struts 2配置文件的根元素 -->

<struts>

<!-- 下面定义了Struts 2框架的一些基础Bean  -->

<bean class="com.opensymphony.xwork2.ObjectFactory" name="xwork" />

<bean type="com.opensymphony.xwork2.ObjectFactory" name="struts"

class="org.apache.struts2.impl.StrutsObjectFactory" />

....

<!-- 下面是一些静态注入Bean定义 -->

<bean class="com.opensymphony.xwork2.util.OgnlValueStack" static="true" />

<bean class="org.apache.struts2.dispatcher.Dispatcher" static="true" />

...

<!-- 下面定义Struts 2的默认包空间 -->

<package name="struts-default">

<!-- 定义Struts 2内建支持的结果类型 -->

<result-types>

<!-- 定义Action链Result类型 -->

<result-type name="chain" class="com.opensymphony.xwork2.

ActionChainResult"/>

<!-- 定义Dispatcher的Result类型,并设置default="true",

指定该结果Result是默认的Result类型 -->

<result-type name="dispatcher"

class="org.apache.struts2.dispatcher.Servlet

DispatcherResult" default="true"/>

<!-- 定义FreeMarker的Result类型 -->

<result-type name="freemarker"

class="org.apache.struts2.views.freemarker.

FreemarkerResult"/>

...

</result-types>

<!-- 定义Struts 2内建的拦截器 -->

<interceptors>

<interceptor name="alias" class="com.opensymphony.xwork2.

interceptor.AliasInterceptor"/>

<interceptor name="autowiring"

class="com.opensymphony.xwork2.spring.interceptor.

ActionAutowiringInterceptor"/>

...

<!-- 定义基本拦截器栈 -->

<interceptor-stack name="basicStack">

<interceptor-ref name="exception"/>

<interceptor-ref name="servlet-config"/>

<interceptor-ref name="prepare"/>

<interceptor-ref name="checkbox"/>

<interceptor-ref name="params"/>

<interceptor-ref name="conversionError"/>

</interceptor-stack>

<!-- 还有系列拦截器栈 -->

...

</interceptors>

<!-- 定义默认的拦截器栈引用 -->

<default-interceptor-ref name="defaultStack"/>

</package>

</struts>

上面的代码并未全部列出struts-default.xml文件,只是列出了每个元素的代表。上面配置文件中定义了一个名字为struts-default的包空间,该包空间里定义了Struts 2内建的Result类型,还定义了Struts 2内建的系列拦截器,以及由不同拦截器组成的拦截器栈,文件的最后还定义了默认的拦截器引用。

这个struts-default.xml文件是Struts 2框架的默认配置文件,Struts 2框架每次都会自动加载该文件。查看我们前面使用的struts.xml文件,看到我们自己定义的package元素有如下代码片段:

<!-- 指定Struts 2配置文件的根元素 -->

<struts>

<!-- 配置名为lee的包空间,继承struts-default包空间 -->

<package name="lee" extends="struts-default">

...

</package>

</struts>

在上面配置文件中,名为lee的包空间,继承了名为struts-default的包空间,struts-default包空间定义在struts-default.xml文件中。可见,Struts 2框架默认会加载struts-default.xml文件。

不仅如此,Struts 2框架提供了一种类似Eclipse的扩展方式,它允许以一种“可插拔”的方式来安装插件,例如后面将要介绍的Spring插件、JSF插件等,它们都提供了一个类似struts2-Xxx-plugin.jar的文件——这个文件就是插件安装文件,只要将该文件放在Web应用的WEB-INF/lib路径下,Struts 2框架将自动加载该框架。

使用WinRAR工具打开struts2-spring-plugin2.06.jar文件,找到一个struts-plugin.xml文件,打开该文件,该文件的代码如下:

<?xml version="1.0" encoding="UTF-8" ?>

<!-- 指定Struts 2的DTD信息 -->

<!DOCTYPE struts PUBLIC

"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

"http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>

<!-- 定义一个名字为spring的ObjectFactory -->

<bean type="com.opensymphony.xwork2.ObjectFactory" name="spring"

class="org.apache.struts2.spring.StrutsSpringObjectFactory" />

<!-- 指定名字为sping的ObjectFactory是Struts 2的ObjectFactory -->

<constant name="struts.objectFactory" value="spring" />

<!-- 定义名为spring-default的包空间 -->

<package name="spring-default">

<!-- 定义整合Spring框架所必需的拦截器列表 -->

<interceptors>

<interceptor name="autowiring"

class="com.opensymphony.xwork2.spring.interceptor.

ActionAutowiringInterceptor"/>

<interceptor name="sessionAutowiring"

class="org.apache.struts2.spring.interceptor.

SessionContextAutowiringInterceptor"/>

</interceptors>

</package>

</struts>

在上面配置文件中,配置了Struts 2与Spring框架整合必需的常量、拦截器等——这也是Struts 2框架使用Spring插件必需的配置。只要将struts2-spring-plugin2.06.jar文件放在WEB-INF/lib路径下,Struts 2框架将自动加载该文件。

 提示  如果用户开发属于自己的Struts 2插件,只要将对应的struts-plugin. xml文件放在JAR文件中,Struts 2框架将自动加载该文件。通过这种方式,Struts 2框架允许使用可插拔的方式管理Struts 2的插件。

3.5.3  struts.properties配置文件

Struts 2框架有两个核心配置文件,其中struts.xml文件主要负责管理应用中的Action映射,以及该Action包含的Result定义等。除此之外,Struts 2框架还包含一个struts.properties文件,该文件定义了Struts 2框架的大量属性,开发者可以通过改变这些属性来满足应用的需求。

struts.properties文件是一个标准的Properties文件,该文件包含了系列的key-value对象,每个key就是一个Struts 2属性,该key对应的value就是一个Struts 2属性值。

struts.properties文件通常放在Web应用的WEB-INF/classes路径下。实际上,只要将该文件放在Web应用的CLASSPATH路径下,Struts 2框架就可以加载该文件。

现在的问题是,struts.properties文件的哪些key是有效的?即struts.properties文件里包含哪些属性是有效的Struts 2属性。下面列出了可以在struts.properties中定义的Struts 2属性。

—  struts.configuration:该属性指定加载Struts 2配置文件的配置文件管理器。该属性的默认值是org.apache.Struts2.config.DefaultConfiguration,这是Struts 2默认的配置文件管理器。如果需要实现自己的配置管理器,开发者则可以实现一个实现Configuration接口的类,该类可以自己加载Struts 2配置文件。

—  struts.locale:指定Web应用的默认Locale。

—  struts.i18n.encoding:指定Web应用的默认编码集。该属性对于处理中文请求参数非常有用,对于获取中文请求参数值,应该将该属性值设置为GBK或者GB2312。

 提示  当设置该参数为GBK时,相当于调用HttpServletRequest的setCharacterEncoding方法。

—  struts.objectFactory:指定Struts 2默认的ObjectFactory Bean,该属性默认值是spring。

—  struts.objectFactory.spring.autoWire:指定Spring框架的自动装配模式,该属性的默认值是name,即默认根据Bean的name属性自动装配。

—  struts.objectFactory.spring.useClassCache:该属性指定整合Spring框架时,是否缓存Bean实例,该属性只允许使用true和false两个属性值,它的默认值是true。通常不建议修改该属性值。

—  struts.objectTypeDeterminer:该属性指定Struts 2的类型检测机制,通常支持tiger和notiger两个属性值。

—  struts.multipart.parser:该属性指定处理multipart/form-data的MIME类型(文件上传)请求的框架,该属性支持cos、pell和jakarta等属性值,即分别对应使用cos的文件上传框架、pell上传及common-fileupload文件上传框架。该属性的默认值为jakarta。

 注意  如果需要使用cos或者pell的文件上传方式,则应该将对应的JAR文件复制到Web应用中。例如,使用cos上传方式,则需要自己下载cos框架的JAR文件,并将该文件放在WEB-INF/lib路径下。

—  struts.multipart.saveDir:该属性指定上传文件的临时保存路径,该属性的默认值是javax.servlet.context.tempdir。

—  struts.multipart.maxSize:该属性指定Struts 2文件上传中整个请求内容允许的最大字节数。

—  struts.custom.properties:该属性指定Struts 2应用加载用户自定义的属性文件,该自定义属性文件指定的属性不会覆盖struts.properties文件中指定的属性。如果需要加载多个自定义属性文件,多个自定义属性文件的文件名以英文逗号(,)隔开。

—  struts.mapper.class:指定将HTTP请求映射到指定Action的映射器,Struts 2提供了默认的映射器:org.apache.struts2.dispatcher.mapper.DefaultActionMapper。默认映射器根据请求的前缀与Action的name属性完成映射。

—  struts.action.extension:该属性指定需要Struts 2处理的请求后缀,该属性的默认值是action,即所有匹配*.action的请求都由Struts 2处理。如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号(,)隔开。

—  struts.serve.static:该属性设置是否通过JAR文件提供静态内容服务,该属性只支持true和false属性值,该属性的默认属性值是true。

—  struts.serve.static.browserCache:该属性设置浏览器是否缓存静态内容。当应用处于开发阶段时,我们希望每次请求都获得服务器的最新响应,则可设置该属性为false。

—  struts.enable.DynamicMethodInvocation:该属性设置Struts 2是否支持动态方法调用,该属性的默认值是true。如果需要关闭动态方法调用,则可设置该属性为false。

—  struts.enable.SlashesInActionNames:该属性设置Struts 2是否允许在Action名中使用斜线,该属性的默认值是false。如果开发者希望允许在Action名中使用斜线,则可设置该属性为true。

—  struts.tag.altSyntax:该属性指定是否允许在Struts 2标签中使用表达式语法,因为通常都需要在标签中使用表达式语法,故此属性应该设置为true,该属性的默认值是true。

—  struts.devMode:该属性设置Struts 2应用是否使用开发模式。如果设置该属性为true,则可以在应用出错时显示更多、更友好的出错提示。该属性只接受true和flase两个值,该属性的默认值是false。通常,应用在开发阶段,将该属性设置为true,当进入产品发布阶段后,则该属性设置为false。

—  struts.i18n.reload:该属性设置是否每次HTTP请求到达时,系统都重新加载资源文件。该属性默认值是false。在开发阶段将该属性设置为true会更有利于开发,但在产品发布阶段应将该属性设置为false。

 提示  开发阶段将该属性设置了true,将可以在每次请求时都重新加载国际化资源文件,从而可以让开发者看到实时开发效果;产品发布阶段应该将该属性设置为false,是为了提供响应性能,每次请求都需要重新加载资源文件会大大降低应用的性能。

—  struts.ui.theme:该属性指定视图标签默认的视图主题,该属性的默认值是xhtml。

—  struts.ui.templateDir:该属性指定视图主题所需要模板文件的位置,该属性的默认值是template,即默认加载template路径下的模板文件。

—  struts.ui.templateSuffix:该属性指定模板文件的后缀,该属性的默认属性值是ftl。该属性还允许使用ftl、vm或jsp,分别对应FreeMarker、Velocity和JSP模板。

—  struts.configuration.xml.reload:该属性设置当struts.xml文件改变后,系统是否自动重新加载该文件。该属性的默认值是false。

—  struts.velocity.configfile:该属性指定Velocity框架所需的velocity.properties文件的位置。该属性的默认值为velocity.properties。

—  struts.velocity.contexts:该属性指定Velocity框架的Context位置,如果该框架有多个Context,则多个Context之间以英文逗号(,)隔开。

—  struts.velocity.toolboxlocation:该属性指定Velocity框架的toolbox的位置。

—  struts.url.http.port:该属性指定Web应用所在的监听端口。该属性通常没有太大的用户,只是当Struts 2需要生成URL时(例如Url标签),该属性才提供Web应用的默认端口。

—  struts.url.https.port:该属性类似于struts.url.http.port属性的作用,区别是该属性指定的是Web应用的加密服务端口。

—  struts.url.includeParams:该属性指定Struts 2生成URL时是否包含请求参数。该属性接受none、get和all三个属性值,分别对应于不包含、仅包含GET类型请求参数和包含全部请求参数。

—  struts.custom.i18n.resources:该属性指定Struts 2应用所需要的国际化资源文件,如果有多份国际化资源文件,则多个资源文件的文件名以英文逗号(,)隔开。

—  struts.dispatcher.parametersWorkaround:对于某些Java EE服务器,不支持HttpServlet Request调用getParameterMap()方法,此时可以设置该属性值为true来解决该问题。该属性的默认值是false。对于WebLogic、Orion和OC4J服务器,通常应该设置该属性为true。

—  struts.freemarker.manager.classname:该属性指定Struts 2使用的FreeMarker管理器。该属性的默认值是org.apache.struts2.views.freemarker.FreemarkerManager,这是Struts 2内建的FreeMarker管理器。

—  struts.freemarker.wrapper.altMap:该属性只支持true和false两个属性值,默认值是true。通常无需修改该属性值。

—  struts.xslt.nocache:该属性指定XSLT Result是否使用样式表缓存。当应用处于开发阶段时,该属性通常被设置为true;当应用处于产品使用阶段时,该属性通常被设置为false。

—  struts.configuration.files:该属性指定Struts 2框架默认加载的配置文件,如果需要指定默认加载多个配置文件,则多个配置文件的文件名之间以英文逗号(,)隔开。该属性的默认值为struts-default.xml,struts-plugin.xml,struts.xml,看到该属性值,读者应该明白为什么Struts 2框架默认加载struts.xml文件了。

在有些时候,开发者不喜欢使用额外的struts.properties文件,Struts 2允许在struts.xml文件中管理Struts 2属性,在struts.xml文件中通过配置constant元素,一样可以配置这些属性。

struts.xml配置片段如下:

<?xml version="1.0" encoding="UTF-8" ?>

<!-- 指定Struts 2的DTD信息 -->

<!DOCTYPE struts PUBLIC

"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

"http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>

<!-- 通过constant元素配置Struts 2的属性 -->

<constant name=" struts.custom.i18n.resources " value="mess" />

...

</struts>

上面代码片段配置了一个常用属性:struts.custom.i18n.resources,该属性指定了应用所需的国际化资源文件的baseName为mess。

 提示  Struts 2提供了两种方式来管理Struts 2的属性:既可以通过struts.properties文件来配置Struts 2属性,也可通过在struts.xml文件中配置constant元素来配置Struts 2属性。

3.5.4  struts.xml文件结构

struts.xml文件是整个Struts 2框架的核心,下面提供了一个最完整的struts.xml文件,这个文件没有任何实际意义,仅仅是一个struts.xml文件示范。

<?xml version="1.0" encoding="GBK"?>

<!-- 下面指定Struts 2配置文件的DTD信息 -->

<!DOCTYPE struts PUBLIC

"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

"http://struts.apache.org/dtds/struts-2.0.dtd">

<!-- struts是Struts 2配置文件的根元素 -->

<struts>

<!-- 下面元素可以出现0次,也可以无限多次 -->

<constant name="" value="" />

<!-- 下面元素可以出现0次,也可以无限多次 -->

<bean type="" name="" class="" scope="" static="" optional="" />

<!-- 下面元素可以出现0次,也可以无限多次 -->

<include file="" />

<!-- package元素是Struts配置文件的核心,该元素可以出现0次,或者无限多次 -->

<package name="必填的包名" extends="" namespace="" abstract=""

externalReferenceResolver>

<!-- 该元素可以出现,也可以不出现,最多出现一次 -->

<result-types>

<!-- 该元素必须出现,可以出现无限多次-->

<result-type name="" class="" default="true|false">

<!-- 下面元素可以出现0次,也可以无限多次 -->

<param name="参数名">参数值</param>*

</result-type>

</result-types>

<!-- 该元素可以出现,也可以不出现,最多出现一次 -->

<interceptors>

<!-- 该元素的interceptor元素和interceptor-stack至少出现其中之一,

也可以二者都出现 -->

<!-- 下面元素可以出现0次,也可以无限多次 -->

<interceptor name="" class="">

<!-- 下面元素可以出现0次,也可以无限多次 -->

<param name="参数名">参数值</param>*

</interceptor>

<!-- 下面元素可以出现0次,也可以无限多次 -->

<interceptor-stack name="">

<!-- 该元素必须出现,可以出现无限多次-->

<interceptor-ref name="">

<!-- 下面元素可以出现0次,也可以无限多次 -->

<param name="参数名">参数值</param>*

</interceptor-ref>

</interceptor-stack>

</interceptors>

<!-- 下面元素可以出现0次,也可以无限多次 -->

<default-interceptor-ref name="">

<!-- 下面元素可以出现0次,也可以无限多次 -->

<param name="参数名">参数值</param>

</default-interceptor-ref>

<!-- 下面元素可以出现0次,也可以无限多次 -->

<default-action-ref name="">

<!-- 下面元素可以出现0次,也可以无限多次 -->

<param name="参数名">参数值</param>*

</default-action-ref>?

<!-- 下面元素可以出现0次,也可以无限多次 -->

<global-results>

<!-- 该元素必须出现,可以出现无限多次-->

<result name="" type="">

<!-- 该字符串内容可以出现0次或多次 -->

映射资源

<!-- 下面元素可以出现0次,也可以无限多次 -->

<param name="参数名">参数值</param>*

</result>

</global-results>

<!-- 下面元素可以出现0次,也可以无限多次 -->

<global-exception-mappings>

<!-- 该元素必须出现,可以出现无限多次-->

<exception-mapping name="" exception="" result="">

异常处理资源

<!-- 下面元素可以出现0次,也可以无限多次 -->

<param name="参数名">参数值</param>*

</exception-mapping>

</global-exception-mappings>

<action name="" class="" method="" converter="">

<!-- 下面元素可以出现0次,也可以无限多次 -->

<param name="参数名">参数值</param>*

<!-- 下面元素可以出现0次,也可以无限多次 -->

<result name="" type="">

映射资源

<!-- 下面元素可以出现0次,也可以无限多次 -->

<param name="参数名">参数值</param>*

</result>

<!-- 下面元素可以出现0次,也可以无限多次 -->

<interceptor-ref name="">

<!-- 下面元素可以出现0次,也可以无限多次 -->

<param name="参数名">参数值</param>*

</interceptor-ref>

<!-- 下面元素可以出现0次,也可以无限多次 -->

<exception-mapping name="" exception="" result="">

异常处理资源

<!-- 下面元素可以出现0次,也可以无限多次 -->

<param name="参数名">参数值</param>*

</exception-mapping>

</action>

</package>*

<struts>

上面的struts.xml配置文件是一个非常全面的配置文件,包含了Struts 2的全部配置元素。上面配置文件主要用于帮助对XML DTD不太熟悉的读者。

实际上,如果读者需要熟悉XML文件的DTD(元素类型定义)语法,通过查看Struts 2配置文件的DTD信息,同样可以了解Struts 2配置文件的结构。下面是Struts 2配置文件的DTD文件代码。

<!--

Struts configuration DTD.

Use the following DOCTYPE

<!DOCTYPE struts PUBLIC

"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

"http://struts.apache.org/dtds/struts-2.0.dtd">

-->

<!ELEMENT struts (package|include|bean|constant)*>

<!ELEMENT package (result-types?, interceptors?, default-interceptor-ref?, default-action-ref?, global-results?, global-exception-mappings?, action*)>

<!ATTLIST package

name CDATA #REQUIRED

extends CDATA #IMPLIED

namespace CDATA #IMPLIED

abstract CDATA #IMPLIED

externalReferenceResolver NMTOKEN #IMPLIED

>

<!ELEMENT result-types (result-type+)>

<!ELEMENT result-type (param*)>

<!ATTLIST result-type

name CDATA #REQUIRED

class CDATA #REQUIRED

default (true|false) "false"

>

<!ELEMENT interceptors (interceptor|interceptor-stack)+>

<!ELEMENT interceptor (param*)>

<!ATTLIST interceptor

name CDATA #REQUIRED

class CDATA #REQUIRED

>

<!ELEMENT interceptor-stack (interceptor-ref+)>

<!ATTLIST interceptor-stack

name CDATA #REQUIRED

>

<!ELEMENT interceptor-ref (param*)>

<!ATTLIST interceptor-ref

name CDATA #REQUIRED

>

<!ELEMENT default-interceptor-ref (param*)>

<!ATTLIST default-interceptor-ref

name CDATA #REQUIRED

>

<!ELEMENT default-action-ref (param*)>

<!ATTLIST default-action-ref

name CDATA #REQUIRED

>

<!ELEMENT global-results (result+)>

<!ELEMENT global-exception-mappings (exception-mapping+)>

<!ELEMENT action (param|result|interceptor-ref|exception-mapping)*>

<!ATTLIST action

name CDATA #REQUIRED

class CDATA #IMPLIED

method CDATA #IMPLIED

converter CDATA #IMPLIED

>

<!ELEMENT param (#PCDATA)>

<!ATTLIST param

name CDATA #REQUIRED

>

<!ELEMENT result (#PCDATA|param)*>

<!ATTLIST result

name CDATA #IMPLIED

type CDATA #IMPLIED

>

<!ELEMENT exception-mapping (#PCDATA|param)*>

<!ATTLIST exception-mapping

name CDATA #IMPLIED

exception CDATA #REQUIRED

result CDATA #REQUIRED

>

<!ELEMENT include (#PCDATA)>

<!ATTLIST include

file CDATA #REQUIRED

>

<!ELEMENT bean (#PCDATA)>

<!ATTLIST bean

type CDATA #IMPLIED

name CDATA #IMPLIED

class CDATA #REQUIRED

scope CDATA #IMPLIED

static CDATA #IMPLIED

optional CDATA #IMPLIED

>

<!ELEMENT constant (#PCDATA)>

<!ATTLIST constant

name CDATA #REQUIRED

value CDATA #REQUIRED

>

通过上面给出的struts.xml配置文件范例,以及Struts 2配置文件的DTD信息,我们已经可以全面掌握Struts 2配置文件的文件结构了,但struts.xml文件各配置元素的意义、各属性的相关含义依然不能深入了解。关于Struts 2配置文件各元素及各属性将在下一章深入介绍。

3.6  本章小结

因为Struts 2是以Struts 1和WebWork为基础的,故本章大致介绍了Struts 1和WebWork框架的MVC实现,并在此基础上侧重于介绍Struts 1和WebWork与Struts 2的延续性,以及Struts 2框架与Struts 1和WebWork的类似性。通过阅读本章,读者应该明白:Struts 2是通过WebWork发展起来的,而不是通过Struts 1发展起来的。

本章还介绍了如何通过Eclipse IDE工具来开发Struts 2应用,Struts 2的配置文件,以及通过web.xml文件加载Struts 2框架。详细介绍了struts.properties文件,以及struts.xml配置文件的结构。关于深入配置struts.xml文件的元素,则放在下一章介绍

时间: 2024-10-05 04:40:43

Struts2框架学习第三章——Struts2基础的相关文章

Struts2框架学习(一)

Struts2框架学习(一) 1,Struts2框架介绍 Struts2框架是MVC流程框架,适合分层开发.框架应用实现不依赖于Servlet,使用大量的拦截器来处理用户请求,属于无侵入式的设计. 2,Struts2框架的流程原理 1)请求先到达Filter中央控制器 2)然后为Action创建代理类 3)将各个服务存放在拦截器中,执行完拦截器后再去执行action类行action类,action类调用service,再调用dao 4)得到结果字符串,创建result对象 5)转向相应的视图.

Struts2框架学习(三) 数据处理

Struts2框架学习(三) 数据处理 Struts2框架框架使用OGNL语言和值栈技术实现数据的流转处理. 值栈就相当于一个容器,用来存放数据,而OGNL是一种快速查询数据的语言. 值栈:ValueStack一种数据结构,操作数据的方式为:先进后出 OGNL : Object-GraphNavigation Language(对象图形导航语言)将多个对象的关系使用一种树形的结构展现出来,更像一个图形,那么如果需要对树形结构的节点数据进行操作,那么可以使用 对象.属性 的方式进行操作,OGNL技

Struts2框架学习(二) Action

Struts2框架学习(二) Action Struts2框架中的Action类是一个单独的javabean对象.不像Struts1中还要去继承HttpServlet,耦合度减小了. 1,流程 拦截器拦截请求,创建代理Action对象,执行方法,返回结果,界面跳转. 拦截器解析请求路径,获取Action的名称,到配置文件中查找action的完整类名,利用反射创建对象. 每请求一次,就创建一个对象,所以action是多例的,也是线程安全的. 2,关系 请求的路径和配置文件的对应关系: 配置文件中包

j2ee开发之struts2框架学习笔记

Struts2框架技术重点笔记 1.Struts2 是在webwork基础上发展而来. 2.Struts2 不依赖struts API和 servlet API 3.Struts2提供了拦截器,表现层技术:jsp +freeMarket+ velocity 4.Struts2可以对指定的方法进行校验,提供了全局范围,包范围和action范围的国际化资源文件的管理实现. 环境搭建:找到对应的jar包 编写struts的配置文件 <?xml version="1.0" encodin

Java Web 学习笔记 第三章 java基础(二)

第三章 java基础(二) 一.转义符 转义字符是"\",通过转义字符,可表示一些特殊的字符. 例如: '\n'  表示回车 '\t'   表示 制表符字符,一个制表符表示向右跳8-10个字符 '\\'   表示\ '\''   表示单引号 '\"'  表示双引号 "\u4e2d"表示unicode编码对应的字符(汉字:中). 二.布尔类型的概念和用法 boolean 类型用来表示肯定或否定两种可能. boolean 常用在分支语句.循环语句中. true

spring框架学习(三)junit单元测试

spring框架学习(三)junit单元测试 单元测试不是头一次听说了,但只是听说从来没有用过.一个模块怎么测试呢,是不是得专门为一单元写一个测试程序,然后将测试单元代码拿过来测试? 我是这么想的.学到spring框架这才知道单元测试原来是这么回事儿. 下面以上一篇文章中set注入的第一个实例为测试对象.进行单元测试. 1,拷贝jar包 junit-3.8.2.jar(4.x主要增加注解应用) 2,写业务类 [java] view plaincopyprint? public class Use

oracle学习 第三章 常用的SQL*PLUS命令 ——02

今天接着昨天的RUN命令继续讲. 3.5 n(设置当前行)命令和A(PPEND)(附加)命令 设想,你输入了例3-10的查询语句 例 3-10 SQL> SELECT ename 2 FROM emp; 例 3-10 结果 看到以上输出时,您发现在SELECT子句中忘了job,sal.这时您又如何修改您的SELECT子句呢?首先您应该使用SQL*PLUS的L(LIST)命令来显示SQL缓冲中的内容. 例 3-11 SQL> L 例 3-11 结果 在例3-11显示的结果中,2后面的"

安卓学习——第三章

安卓学习——第三章 由于自身的实力不足,经过尝试后放弃了自己编写记账本app,而是打算找到合适的相关项目进行学习.我找到了几个AndroidStudio项目,我在AndroidStudio里面直接打开文件,发现无法运行.想到应该是import项目才行(我可真是菜的真实). 通过import这些项目之后,发现其中一个项目竟然是可以跑起来的.我便将项目通过手机进行测试,发现在手机上也是可以运行的.不过有一些在外观上的问题. 首先是在手机上的显示,会有一部分文字内容是乱码.我便去找编译器里面相关文件的

Struts2框架学习第一章——Struts2概述

本章要点 —  Web应用的发展 —  Model 1和Model 2 —  MVC思想 —  MVC模式的优势 — 常用MVC框架及其特征 —  Struts 1的基本结构及其存在的问题 —  WebWork的基本结构 —  Struts 2的起源 —  Struts 2的框架架构 —  Struts 2的标签库 —  Struts 2的控制器组件 —  Struts 1和Struts 2的对比 Struts 1是全世界第一个发布的MVC框架,它由Craig McClanahan在2001年发