1.Struts2的核心——拦截器(interceptor):
拦截器是用于在Action或者某个方法调用之前进行特定的处理的对象,类似于过滤器,是一个特殊的Servlet。拦截器主要用于在调用Action或Action方法之前做输入校验、权限验证,字符编码转换等一些通用操作。多个拦截器构成拦截器栈。Struts2中有一个默认的拦截器栈,在每个Action调用之前执行。
拦截器三个对象:被拦截对象,拦截器对象本身,代理。
真正执行的不想目标对象,而代理。
拦截器要实现Interceptor接口,默认实现拦截器时继承AbstractInterceptor类,而很少直接继承Interceptor接口。
2.类拦截器和方法拦截器:
(1).针对Action进行拦截处理的拦截器是类拦截器,是一种粗粒度的拦截器。
拦截器是一种特殊的Servlet,与过滤器类似,其init()和destroy()方法只执行一次。而intercepte()方法是action每次执行时都会执行一次。
(2).只对Action中某个特定方法进行拦截处理的拦截器就是方法拦截器,方法拦截器与类拦截器不同,它继承MethodFilterInterceptor类,实现doIntercepte()方法。
3.配置类拦截器:
(1).在Struts2的配置文件struts.xml中的<package>元素标签下添加:
注意:在配置拦截器时传递了参数,需要在拦截器中定义和参数名称相同的属性,并且生成set和get方法。定义时为默认参数,拦截器引用时参数为动态参数,动态参数覆盖默认参数。
(2).对Action引入拦截器:
在Struts2的配置文件struts.xml中要引入拦截器的Action的<action>元素标签下添加:
4.配置拦截器栈:
多个拦截器构成拦截器栈。
(1).拦截器栈定义方法:
在Struts2的配置文件struts.xml中的<package>元素标签下添加:
注意:拦截器栈中可以包含拦截器和拦截器栈。
(2).Action中引入拦截器栈:
和引入拦截器相同:
注意:Struts2的Action配置了一个默认的拦截器栈,如果在Action中引入了自定义的拦截器或者拦截器栈之后,默认的Struts2默认的拦截器和拦截器栈就不会自动添加到该Action上,如果想使用默认的拦截器和拦截器栈就必须手动添加。
5.方法拦截器的配置:
(1).配置拦截器:
和配置类拦截器和拦截器栈相同。
(2).Action中引入方法拦截器:
在Struts2的配置文件struts.xml中要引入拦截器的Action的<action>元素标签下添加:
注意:include的优先级高于exclude。
6.Struts2中的文件上传和下载:
Struts2中文件上传和下载的的组件是FileUpload和IO(commons类包)依赖包。
7.Struts2文件上传:
(1).JSP页面表单属性设置如下:
(2).JSP页面表单中文件上传字段类型设置为“File”,如:
(3).Action中的处理逻辑:
a.Aciton中用File类型的属性接收页面的文件输入流,如果是批量上传文件,则使用File集合。
b.在Action中将该输入流写到要保存上传文件的目录即可。核心代码如下:
8.Struts2上传文件时的配置
(1).在Struts2的配置文件struts.xml中修改Struts2的默认字符编码:
(2).在Struts2的配置文件struts.xml中指定上传文件的临时保存目录:
(3).限制上传文件的大小、类型等,要在上传的Action手动添加fileUpload拦截器(Struts2默认已配置,按照下面格式引用并添加参数即可),添加自定义参数:
9.Struts2的文件下载:
(1).在文件下载Action中写一个获取文件输入流的方法,如:
(2).在Struts2的配置文件struts.xml中配置文件下载Action,如:
10.修改Struts2的默认属性方法:
(1).方法1:在Struts2配置文件struts.xml中添加<constant>标签。
(2).方法2:在/src目录下使用struts.properties属性文件方式。
(3).方法3:在web.xml文件中Struts2的过滤器中添加<init-param>标签,传递初始化参数。
11.当Struts的配置文件过大时,建议将其分模块配置,然后在一个总的配置文件中加载进来,
使用<include file=”分模块配置文件”/>方法。
12.Struts2的属性驱动和模型驱动:
(1).在Struts2的Action中,将页面表单域变为Action类对应的属性的方法称为属性驱动,是Struts2最常用的方式。
(2).Struts2还支持模型驱动方式,即将所有的属性封装为一个JavaBean,类似于Struts1中的ActionForm,而在Action只负责业务逻辑的处理,这种方式成为模型驱动。
注意:使用模型驱动时,Struts2的Acion必须实现ModelDriven<T>接口,它是一个泛型接口,T的类型为封装的模型类型。
13.Struts2防止表单重复提交:
(1).在JSP页面中使用<s:token>标签,为每次提交的表达生成一个标志。
(2).定义Token拦截器,实现Preparable接口,实现其prepare()方法,该方法县域Action的方法执行,在prepare()方法中记录和比较提交表单的token。
(3).在Struts2的配置文件中,为Action配置token拦截器,同时在Action中添加配置:
<result name=”invalid.token”/>指定表达重复提交的处理页面。
14.Struts2中获取和设置请求的属性或者参数:
(1).Struts2的Action中,ActionContext.getContext().put(key, value);方法,对应于Servlet中的request.setAttribute(key, value);方法。
ActionContext.getContext().get(key);方法,对应与Servlet中的request.getAttribute(key);方法。
(2).Struts2中,ServletActionContext.getServletContext()就获得了Servlet的上下文请求对象,可以像使用request对象一样使用了。
(3).Struts2中,也可以实现ServletRequstAware接口,实现其setServletRequest方法,this.request=request;然后就可以像Struts1一样方便使用request对象了。
综上:推荐使用ActionContext对象,因为它是Struts2的本身的对象,降低了与Servlet容器的耦合度。
15.Struts2的动态方法调用:
(1).方法一:在Struts2配置文件struts.xml中的Action中添加method=”业务方法名”属性。
这种方法最常用,推荐使用。
(2).方法二:不用在Struts2配置文件struts.xml中的Action中添加method属性,直接在页面中使用:action=”配置文件中配置的Action名称!业务方法名.action”。
(3).方法三:使用通配符,不推荐使用。
16.Struts2的异常处理:
(1).在在Struts2配置文件struts.xml中添加异常配置:
(2).也JSP页面上显示异常信息:
也可以使用EL表达式:${exception.message}。
17.Struts2也Spring的集成:
Struts2侧重于页面端逻辑的处理,Spring侧重于业务逻辑方面的处理,Hibernate侧重于数据持久化的处理,SSH集成是最流行的使用方式,其中Spring是核心,通过Spring可以管理和调用Struts和Hibernate。这里着重说明Struts2和Spring的集成。
(1).在WEB-INF/lib下加入struts2-spring-plugin.jar插件(Struts2提供的和Spring集成的依赖包)。
(2).对工程引入Spring支持:将Spring相关的jar包加入到WEB-INF/lib目录下,同时在/src目录下创建spring的配置文件。
(3).将Struts2配置文件struts.xml中的action的class配置到Spring的配置文件中,即Struts2的Action交由Spring负责创建和管理。
(4).在web.xml配置文件中加入spring启动的事件监听器,同时指定Spring的配置文件:
至此Struts2和Spring就无缝集成起来。
注意:spring中创建的bean默认是singleton(单态)的,而Struts2的Action应当是每次请求调用当会创建一个新的对象,因此需要在Spring配置文件中的Struts2的Action添加scope=”prototype”属性,指定Action是原型。