==============================================
一、获取request、response
==============================================
struts2的action抛弃了request、response等servlet API,是业务层更加独立。但是有时候需要使用request、response。例如从request中获取session、往response里面写cookie等。从struts2中获取request、response有两种途径。
1、利用ServletActionContext的静态方法
struts2利用ServletActionContext类来维护servlet对象,把servlet对象(如request、response、application、session等)放到了ServletActionContext中。ServletActionContext利用ThreadLocal来维护不同线程的servlet对象,因此可以使用ServletActionContext来获取servlet对象。这种方式也可以叫做非注射方式(非IoC方式),举例如下:
LoginAction.java
package com.lmb.struts2.action;
import java.io.File;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class LoginAction extends ActionSupport{
private String account;//账号
private String password;//密码
public String login() throws Exception{//登陆方法
HttpServletRequest request=ServletActionContext.getRequest();//获取request
HttpServletResponse response=ServletActionContext.getResponse();//获取response对象
HttpSession session=request.getSession();//获取session
session.setAttribute("account", account);//将帐户名放到session中
ServletContext context=ServletActionContext.getServletContext();//获取上下文
File uploadFile=new File(context.getRealPath("upload"));//获取upload文件夹
return execute();
}
}
虽然是使用静态方法获取的request、response,但仍然能保证获取到当前用户以及当前线程的request、response,不会发生混淆。因为struts2使用ThreadLocal来维护当前线程的request、response等数据。
2、利用相关的Aware接口
struts2提供了Aware接口。Aware接口是“感知”的意思,实现了Aware接口的action能够感知相应的资源。struts在实例化action实例时,如果发现它实现了相应的Aware接口,会把相应的资源通过Aware接口方法注射进去。这种方法也叫做注射方式(IoC方式)。
servlet API中常用对象有request、response、application、session,对应的Aware接口分别为ServletRequestAware、ServletResponseAware、ServletContextAware、SessionAware。举例如下:
ServletAwareAction.java
package com.lmb.struts2.action;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionSupport;
public class ServletAwareAction extends ActionSupport
` implements ServletRequestAware,ServletResponseAware,ServletContextAware, SessionAware(){
private ServletContext application;//Servlet上下文对象
private HttpServletRequest request;//request对象
private HttpServletResponse response;//response对象
private Map session;//session对象
public void setServletContext(ServletContext application) {
this.application = application;
}
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
public void setServletResponse(HttpServletResponse response) {
this.response = response;
}
public void setSession(Map session) {
this.session = session;
}
public String execute(){
String upload=application.getRealPath("upload");//使用application
request.getRemoteAddr();//使用request
response.getContentType();//使用response
session.get("account");//使用session
return Action.SUCCESS;
}
}
实现了ServletRequestAware接口便会有一个setServletRequest()方法来获取request对象。
实现了ServletResponseAware接口便会有一个setServletResponse()方法来获取response对象。
实现了ServletContextAware接口便会有一个setServletContext()方法来获取ServletContext的applic对象。
实现了SessionAware接口便会有一个setSession()方法来获取session对象。要注意的是,SessionAware接口的setSession()方法的参数是Map类型,该Map代表session内存储的各种数据。
Aware接口其实是一种拦截器,拦截器代码会在执行action之前执行,将相关的servlet对象设置进来。
==============================================
二、使用Validator校验数据
==============================================
跟struts1一样,struts2也提供了数据校验。这种数据校验是配置式的,既可用XML配置,也可以用、java注解(@Annotation)配置。struts2提供了许多默认的校验器,例如:数字校验器、电子邮件校验器等,配置一下即可用。
1、使用XML配置数据校验Validator
使用XML配置时,需要在action类所在的package内添加一个XML文件,文件名格式为action类名-validation.xml或者action类名-action别名-validation.xml。如果action中有多个方法,一般使用后者。例如:BookAction-addBook-validation.xml、BookAction-initAddBook-validation.xml等。支持校验的action必须实现Validateable接口,一般继承ActionSupport就可以了。
下面对addBook.action进行校验,首先将BookAction继承ActionSupport以支持校验。校验配置XML文件名应为BookAction-addBook-validation.xml,位置与BookAction.class位于同一包下。校验内容为:添加书籍时,书籍名称与作者必须填写,如果填写了日期,日期格式必须正确,并位于指定的格式内。校验配置代码如下:
BookAction-addBook-validation.xml
<validators>
<field name="book.name"> <!-- 检查书名 -->
<field-validator type="requiredString"> <!-- 必需的 -->
<param name="trim">true</param><!-- 检查时去掉前后空格 -->
<message>请输入书籍名称</message> <!-- 提示信息 -->
</field-validator>
</field>
<field name="book.author"> <!-- 检查作者,必须非空 -->
<field-validator type="requiredString"> <!-- 必需的 -->
<message>请输入书籍作者</message> <!-- 提示信息 -->
</field-validator>
</field>
<field name="book.publishedDate">
<field-validator type="Date"> <!-- 必需的 -->
<param name="min">1900-01-01</param><!-- 最小值 -->
<param name="max">2200-01-01</param><!-- 最大值 -->
<message><![CDATA[日期格式必须位于100-01-01与2200-01-01之间]]></message> <!-- 提示信息 -->
</field-validator>
</field>
</validators>
配置完毕后不需要更改任何的JSP代码。struts2的表单标签支持校验错误信息显示(而不用像struts1那样还需要用<html:error />显式的调用
)。如果数据校验失败,会转到input页面显示错误信息,因此action配置中要配置名为input的JSP页面。
2、配置客户端Validator
以上的校验是在服务器端完成的。**struts2也支持客户端javascript校验。方法很简单,再将JSP的<struts:form>
标签加上validate=”true”属性即可。**struts2的客户端校验与struts1不同,struts1使用了提示框显示错误信息,struts2抛弃了烦人的提示框,显示错误的方式与服务器端校验完全一样,直接在页面内进行显示。客户端校验是通过javascript实现的,因此struts2会自动加载相应的javascript类库。
3、常用的Validator
4、使用@Java注解配置Validator
struts2也支持使用java注解配置数据校验。Action类同样需要继承自ActionAupport类,并用@Validation注解,表示该Action需要数据校验。然后在方法上配置@Validations。@Validations可指定多条校验规则,具体实例如下:
BookAction.java
package com.lmb.struts2.action;
@Validation
public class BookAction extends ActionAupport{
public static List<Book> bookList=new ArrayList<Book>();
private Book book;
private String title;
//增加书籍页面
@Validations(
requiredStrings={
@RequiredStringValidator(type=ValidatorType.SIMPLE,trim=true,fieldName="book.name",message="请输入书名.*"),
@RequiredStringValidator(type=ValidatorType.SIMPLE,trim=true,fieldName="book.author",message="请输入书籍作者.*"),
},
dateRangeFields={@DateRangeFieldValidator(
type=Validator.SIMPLE,fieldName="book.publishedDate",min="1900-01-01",
max="2200-01-01",message="日期必须大于${min}小于${max},当前值为${book.publishedDate}.")})
public String add(){
bookList.add(book);
title="<br/><br/>添加书籍成功<br/><br/>";
}
@SkipValidation //书籍列表,@SkipValidation跳过校验
public String list(){
return "lis
t";
}
}
该配置与上面的XML配置是等价的。因为只对addBook.action进行校验,因此只要在方法add()上添加@Validation以及校验规则。其他不需要校验的方法需要加上@SkipValidation,否则也会被校验。
另外,Validator时struts2默认的校验方式是全局验证模式。因此只能配置一种验证方式。如果要如果要对同一个Action的两个方法配置两种不同的验证方式,需要重写struts2的默认拦截器。
注意:被校验的Action类要继承ActionSupport类,并要在action配置中指定名为input的JSP,因此struts2在校验失败后会自动返回input页面。