06.Struts2中的拦截器及类型转换
1、什么是拦截器
拦截器(Interceptor):
拦截器是Struts2的核心,Struts2的众多功能都是通过拦截器来实现的。
2、拦截器的作用
作用:拦截用户的请求,对请求进行一些预处理,当请求完毕之后,又可以对请求进行后续的处理,对相应进行后续的处理。作用和过滤器很类似。
3、 拦截器的配置
1)编写实现Interceptor 接口的类。
2)在struts.xml文件里定义拦截器。
3)在action中使用拦截器 。
<!-- 让该package使用其中定义的拦截器栈 -->
<interceptors>
<!-- 拦截器栈名 -->
<interceptor-stack name="myInterceptor"><!--name:见名知意-->
<!-- 引用预先调用pramas的拦截器栈 -->
<interceptor-ref name="paramsPrepareParamsStack">
<param name="prepare.alwaysInvokePrepare">false</param>
</interceptor-ref>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="myInterceptor"></default-interceptor-ref>
在程序中的使用如下:
action动态的添加
输入验证(验证用户输入的是否正确)
对象组装(将用户输入的数据转换为对象的属性)
权限控制(如访问者为登录用户)
日志记录(记录action的执行情况)
这些操作都可以通过拦截器实现,而不用修改action
4、拦截器的工作流程
Action命令(执行)–>拦截器1–>拦截器2–>拦截器n–>Action–>拦截器1–>拦截器2–>拦截器n(返回)–>Action命令
5、自定义类型转换器
概述:在Struts2中,支持全局类型转换和局部类型转换两种方式。所谓全局类型转换,即在所有的action/model中,都用同一个类型转换器来转换某种特定类型的对象;而局部类型转换,意思就是针对某个action/model中的属性所定义的特定的类型转换器。
1)全局类型转换
-
即针对整个系统中同样类型的属性定义转换器
只需:
1、 在类路径的根目录下定义xwork-conversion.properties文件(命名必须一致)
2、 在文件中用这样的格式声明哪个类型使用哪个转换器:
属性类型的全路径类名=转换器的全路径类名
3、 Struts2将能自动发现这个文件,并根据其中的定义,对特定的类型调用你指定的类型转换器进行类型转换
案例1:
Point类型
package cn.com.leadfar.model;
public class Point {
private int left;
private int right;
public int getLeft() {
return left;
}
public void setLeft(int left) {
this.left = left;
}
public int getRight() {
return right;
}
public void setRight(int right) {
this.right = right;
}
}
Point类型的转换器
package cn.com.leadfar.struts2.actions;
import java.util.Map;
import org.apache.struts2.util.StrutsTypeConverter;
import cn.com.leadfar.model.Point;
public class PointConverter extends StrutsTypeConverter {
@Override
public Object convertFromString(Map context, String[] value, Class toType) {
//TODO 前提条件判断
String p = value[0];
String[] ps = p.split(",");
int left = Integer.parseInt(ps[0]);
int right = Integer.parseInt(ps[1]);
Point point = new Point();
point.setLeft(left);
point.setRight(right);
return point;
}
@Override
public String convertToString(Map context, Object point) {
Point p = (Point)point;
return p.getLeft()+"-"+p.getRight();
}
}
xwork-conversion.properties文件的内容如下:
<!--属性类型的全路径类名=转换器的全路径类名-->
cn.com.leadfar.model.Point=cn.com.leadfar.struts2.actions.PointConverter
2)局部类型转换
即针对某个Action或Model的属性定义的转换器
1、在与Action/Model类同一个包下面,定义 Action/Model类名-conversion.properties文件
2、文件内部用这样的格式来声明哪个属性需要用哪个类型转换器:
属性名*=*转换器的全路径类名
案例2:
java.util.Date类型,可以声明不同的类使用不同的类型转换器
package cn.com.leadfar.model;
import java.util.Date;
public class User {
private Date endDate;
public Date getEndDate() {
return endDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
}
package cn.com.leadfar.struts2.actions;
import java.util.Date;
import cn.com.leadfar.model.Point;
import cn.com.leadfar.model.User;
import com.opensymphony.xwork2.ModelDriven;
public class UserAction implements ModelDriven{
private User user;
private Date beginDate;
@Override
public Object getModel() {
if(user == null){
user = new User();
}
return user;
}
public String add(){
return "success";
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Date getBeginDate() {
return beginDate;
}
public void setBeginDate(Date beginDate) {
this.beginDate = beginDate;
}
}
例如:UserAction类中的beginDate属性和User类中endDate属性,分别使用不同的类型转换器
package cn.com.leadfar.struts2.actions;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Map;
import org.apache.struts2.util.StrutsTypeConverter;
public class BeginDateConverter extends StrutsTypeConverter {
private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
@Override
public Object convertFromString(Map context, String[] value, Class toType) {
String d = value[0];
try {
return format.parse(d);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
@Override
public String convertToString(Map context, Object date) {
return format.format(date);
}
}
package cn.com.leadfar.struts2.actions;
import java.text.ParseException;