structs2总结

一.Structs2的helloworld

1.加入Struts2所依赖jar包到tomcat容器webapps 下面项目目录下面的 \WEB-INF\lib\

2.web.xml配置我们的核心控制器StrutsPrepareAndExecuteFilter

3.新建一个Action类,处理业务逻辑

4.在classpath下新建struts.xml文件,注册Action类

5.访问action:http://localhost/appName/<PackageNamespace>/<ActionName>.<Extension>

<PackageNamespace> 代表你在struts.xml中配置package的namespace,action配置中name! <Extension>默认可不写或者是.action

二、Structs2配置文件

分为内部配置文件和开发人员使用的配置文件。其中,内部配置文件由Structs2框架自动加载,对其自身进行配置,如structs-default.xml和structs-plugin.xml;外部配置文件由开发人员使用,如web.xml,structs.xml等。

1.在根元素<struts>下可以使用include子元素引入其他的配置文件,这样可以将各个模块分散在不同的配置文件中进行配置。

2.package元素下可以定义全局视图,如果两个package要共享相同的全局视图,那么为它们定义一个相同的父包。

3.<action>元素的method属性可以不设置,默认为executeclass属性可以不设置,默认为ActionSupport

4.<result>元素的type属性和name属性都可以不设置,默认值分别为dispatcher和success。当<result>元素中只有默认的<param>子元素要设置时,可以将该<param>子元素中的内容直接写在<result>标签中。

5.在<package>元素下配置<default-action-ref>子元素,用于说明在该包下不存在的action路径映射,都可以统交给一个默认的<action>元素去处理。

6.在<package>元素下配置<default-class-ref>子元素,用于说明默认的Action类是可以进行配置修改的。

7.在根元素<struts>下可以使用constant子元素配置常量。

8.从strut2的核心jar包内的org.apache.struts2包下的default.properties文件中可以看到 各个常量的注释说明,典型几个常量:

<constant name="struts.action.extension" value="do,go"/>配置访问Action的后缀,可以配置多个后缀名。 提示:default.properties文件中为该常量配置了一个空字符串。

<constant name="struts.devMode" value="true"/>可以让struts在控制台中打印出更多的信息和重新加载配置文件。

<constant name="struts.enable.DynamicMethodInvocation" value="false"/>可以配置不支持动态方法调用。

<constant name="struts.configuration.xml.reload" value="true"/>可以让struts重新加载配置文件,但不会导致web应用重新启动。

9.常量可以在下面多个文件中进行定义,struts2加载常量的搜索顺序如下,后面的设置 可以覆盖前面的设置:

default.properties文件

struts-default.xml

struts-plugin.xml

Struts.xml(建议放到该文件中)

struts.properties(为了与webwork向后兼容而提供)

web.xml

三、Structs2处理流程

当用户发出请求后,web.xml中的StrutsPrepareAndExecuteFilter核心控制器进行拦截过滤。一般情况下,它负责拦截所有的用户请求。默认情况下,如果用户的请求路径不带后缀或者以".action"结尾,这是请求将被转入structs2框架处理,否则structs2忽略请求。当请求转入structs2框架时会先经过一系列的拦截器,然后再到action。与structs1不同,structs2对用户的每一次请求都会创建一个action,所有structs2中的action是线程安全的。

四、包与Action的定位

如果不存在相应的包,则查找上一层的包名,注意,只要一旦追溯到了一个最匹配的上层包名,不管这个包中是否存在要访问的Action,都不会再追溯更上层的包名了。如果struts2定位到的包名中不存在当前要访问的Actionstruts2接着还会在默认名称空间寻找该Action,只有在默认名称空间的包名中还没找到该action时,才报错action找不到的错误。注意("/"也算是一个包,只是这个包比较特殊!

五、拦截器(interceptor)

1.自定义拦截器

<1>定义一个类实现interceptor接口

<2>在structs.xml中注册拦截器

<3>为action应用拦截器

2.其他

<1>一旦为某个action显式指定了某个拦截器,则所属包中定义的默认拦截器将不起作用。

<2>如果想保留structs2的拦截器,又想使用我们自定义的拦截器,可以定义一个拦截器栈。

<3><default-interceptor-ref name="defaultStack"/>把拦截器定义为默认的拦截器。每个包只能定义一个默认的拦截器。

六.输入校验

可以对action中的指定方法和所有方法进行校验。

1.提供了两种实现方式

采用手工编写代码实现

基于xml配置方式实现

2.手工编写代码对action中所有方法进行校验

通过重新validate()方法实现,当某个数据校验失败时,应该调用addFieldError()方法往系统的fieldErrors添加校验失败信息。为了使用addFieldError()方法,action可以继承ActionSupport,如果系统的fieldErrors包含失败信息,structs2会将请求转发到名为input的result,在input视图中可以通过<s:fielderror/>显示失败信息。

<1>提供validate方法

<2>提供input视图,一般该视图为提交信息的页面。

<3>在编辑页面导入s标签,使用<s:fielderror/>显示失败信息。

3.手工编写代码对action中指定方法进行校验

通过validateXxx()方法实现,它之后校验action中方法名为xxx的方法。

4.输入校验流程

<1>类型转换器对请求参数执行类型转换,并把转换后的值赋给action中的属性。

<2>如果在执行类型转换的过程中出现异常,系统会将异常信息保存到ActionContext,conversionError拦截器将异常信息封装到fieldError里。不管类型转换是否出现异常,都会进入第3步。

<3>系统通过反射技术先调用action中的validateXxx()方法,Xxx为方法名。

<4>再调用action中的validate()方法。

<5>经过上面四个步骤,如果系统中的fieldErrors存在错误信息(即存放错误信息的集合的size大于0),系统自动将请求转发至名称为input的视图。如果系统中的fieldErrors没有任何错误信息,系统将执行action中的处理方法。

注意:如果确认validate方法中没有问题,但还是跳到input视图时,需要判断类 型是否转换失败。

5.基于xml方式对action中所有方法进行校验

使用xml配置方式实现输入校验,action也需要继承ActionSupport,并且提供校验文件,校验文件和action类纺织同一个包下。文件的取名格式为:ActionClassName-validation.xml。

采用配置文件校验方式校验后,Action中的validatable有关的校验方法也会执行,且配置文件校验方式在validate校验方法之前执行。

系统定义的校验器在xwork-2.x.jar中...validators包下的default.xml中找到。

6.基于xml方式对action中指定方法进行校验

xml文件的取名格式为:ActionClassName-actionName-validation.xml 。如:

UserAction-user_add-validation.xml(action的名称是由url路径决定的)。

在处理请求方法上使用@SkipValiation注解,配置文件校验方式也将无效。

7.基于xml校验的一些特点

当为某个action提供了所有方法和指定方法校验两种规则时,系统会先寻找所有方法的校验文件,然后继续寻找指定方法的校验,当寻找完所有的相关校验文件后,会将所有的校验规则进行汇总,然后全部应用于action的校验。如果两个校验文件中指定的校验规则发生冲突,则只使用后面文件中的校验规则。

当action继承了另一个action,父类的action校验文件会先被搜索到。

七、接收请求参数

1.采用基本类型接受请求参数(get/post)

在action类中定义与请求参数同名的属性,structs2便能自动接受请求参数并赋予给同名属性。如:

请求路径:http://localhost/test/view.action?id=78

public class ProductAction{

public Integer id;

setter和getter.......

}

structs2通过反射技术调用与请求参数同名的属性的setter方法来获取请求参数值。

2.采用复合类型接收请求参数

请求路径:http://localhost/test/view.action?product.id=78

public class ProductAction{

private Product product;

setter和getter.....

}

Structs2首先通过反射技术调用Product的默认构造器创建product对象,然后通过反射技术调用product中的请求参数同名的属性的setter方法来获取请求参数值。

3.其他

<1>Struts框架在把请求交给action的业务方法去处理之前,可以将请求参数来填充到Action的相应属性中,所以,对于请求消息中的每个参数(包括网页表单中的每个字段),Action中 通常都有一个对应的属性来接受相应的参数值。

<2>在action的业务方法中也可以访问Servlet API,通过request.getParameter获得参数,框架使用中不建议这种方法。

<3>在structs2.1.6的版本中,会出现中文乱码问题,可以自己写一个filter,在structs2之前进行过滤。

八、文件上传

1.要想让浏览器把文件内容也传给服务器,必须将form表单的enctype属性设置为"multipart/form-data",提交方式必须是post。

2.文件过大,请求将会被拒绝。在structs.xml中可以更改它的最大文件上传限制。

<constant name="struts.multipart.maxSize" value="60000"></constant>

3.文件上传action类中的命名一定要符合structs2的规范。

上传文件的名称必须是:上传文件+FileName;

上传文件的类型必须是:上传文件+ContentType。

如:上传文件名称为:uploadFiles,则上传文件的名称命名是uploadFilesFileName上传文件的类型命名为uploadFilesContentType,切勿写成uploadFileFileNames。

九、通配符

1.在action元素的name属性中可以使用*通配符,它可以匹配除了"/"以外的多个连续字符,在action元素的class和method属性以及result元素中可以引用*通配符在访问期间实际匹配的内容。

2.如果*匹配的内容为空,则调用execute方法;对于采用下划线连接*的方式,如果访问路径中没有为*部分指定内容,那么在访问路径中还可以省略下划线。

3.使用*通配符可能导致有多个action元素与一个访问路径匹配,这时候以排在配置文件中最后的配置项为准,所以更具体的模式应在更不具体的模式之后进行配置。

十、Structs2的工作原理

structs2总结

上图来源于Struts2官方站点,是Struts 2 的整体结构。
一个请求在Struts2框架中的处理大概分为以下几个步骤
1 客户端初始化一个指向Servlet容器(例如Tomcat)的请求
2 这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin)
3 接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请是否需要调用某个Action
4 如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy
5 ActionProxy通过Configuration Manager询问框架的配置文件,找到需要调用的Action类
6 ActionProxy创建一个ActionInvocation的实例。
7 ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。
8 一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可 能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。在表示的过程中可以使用Struts2 框架中继承的标签。在这个过程中需要涉及到ActionMapper

在上述过程中所有的对象(Action,Results,Interceptors,等)都是通过ObjectFactory来创建的。


ActionMapper和ActionMapping

ActionMapper接口是HTTP请求和action调用请求之间提供了一个映射。当给定一个HTTP请求时,ActionMapper会根据请求的URI来查找是否有对应的action调用,有则返回一个描述action调用的ActionMapping,如果没有找到对应的action调用,则返回null。ActionMapping本质上是一个数据传输对象,它将Action类和要执行的方法的详细资料收集在一起。ActionMapping是由org.apache.structs2.dispatcher.mapper.Dispatcher和各种用户接口组件组成的。

ActionProxy和ActionInvocation

ActionProxy是在XWork和真正的action之间充当代理角色,在通过框架执行action的过程中,因为使用的是代理而不是直接操纵对象,所以在代理中封装拦截器、result等二外的代码。ActionProxy持有ActionInvocation对象。ActionInvocation代表了action执行的当前状态。它持有拦截器(按顺序排列),Action实例,结果映射和ActionContext.

ActionContext

它是action执行的上下文环境。每一个上下文相当于action执行所需要的一组对象的容器,例如session,application,parameters,locale等。ActionContext包含了大量执行期间有用的环境信息。这些信息由org.apache.structs2.dispatcher.Dispatcher在创建ActionProxy前设置,并封装到一个Map对象extraContext中,该对象随后被当做参数传递到ActionProxyFactory的createActionProxy()方法中。ActionContext是线程本地的,线程是安全的。

ObjectFactory

它是负责构建核心框架对象的。用户可以自己注册自己的ObjectFactory实现来控制这些对象的实例化。使用方法:定制的ObjectFactory必须直接或者间接的继承自com.opensymphony.xwork2.ObjectFactory类,并要求提供一个默认的无参数的构造方法。注册自己的ObjectFactory可以在CLASSPATH的根路径下创建structs.properties,然后输入下面的内容:::structs.obejctFactory=MyObjectFactory

这样就会把转化成功了。

result

每一个action执行都会返回一个String类型的结果码,用于从配置的result元素列表中选择对应的result。result在structs.xml中配置。


你可能感兴趣的:(struct)