Struts2如何接收请求参数?
Action实现多个处理逻辑
即一个action类可以有多个method方法,实现方式有三种
1.动态方法调用
2.为Action指明method属性
3.使用通配符,建议使用,‘1’代表第一个‘*’的内容
<action name="XX_*" class="" method="{1}">
接收基本类型
请求:http://…/test.action?id=24
action:
private int id;
public void setId(int id){
this.id = id;
}
在Action类中定义同名属性及setter(),struts2就能自动接收请求参数并赋值。
接收复合类型
请求:http://…/test.action?user.id=24
action:
private User user;
public void setUser(User u){
this.user = u;
}
注意请求中的user要与action中的user同名,相当于,Struts先通过反射创建user对象,然后再向user的同名id属性注值。
中文乱码
如果请求是以post的方式提交的,那么可以在web.xml新建一个Filter,把它放在Struts的Filter之前,然后在doFilter()里添加以下代码。
public void doFilter(...){
HttpServletRequest req = (HttpServletRequest) request;
req.setCharacterEncoding("UTF-8");
filterchain.doFilter(request, response);
}
类型转换器
Struts2有局部和全局类型转换器两种。实现方式如下:
- 实现TypeCoverter接口
- 继承DefaultTypeConverter
- StrutsTypeConverter
如何自定义类型转换器?
1.action类:
private Date date;
setDate()...;
getDate()...;
2.转换器类:
public class DateConverter extends DefaultTypeConverter {
@Override
public Object convertValue(Map context, Object value, Class toType) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
try {
if(toType == Date.class){//String-->Date
String[] params = (String[]) value;// Request.getParameterValues()
return dateFormat.parse(params[0]);
}else if(toType == String.class){//Date-->String
Date date = (Date) value;
return dateFormat.format(date);
}
} catch (ParseException e) {}
return null;
}
}
3.注册:
局部—在Action类所在包下放置配置文件
文件名:ActionClassName-conversion.properties
内容:属性名称 = 类型转换器的全类名
—DateAction-conversion.properties
——date = com.ejob.conversion.DateConverter
全局—在src下放置配置文件
文件名:xwork-conversion.properties
内容:待转换的类型 = 类型转换器的全类名
—xwork-conversion.properties
——java.util.Date = com.ejob.conversion.DateConverter
Action如何访问Servlet api?
struts2的Action并未与任何Servlet API耦合,但对于web应用的控制器而言,我们必须要访问某些Servlet API,例如有时需要获得session或application,并向其设置属性。
1. ActionContext
ActionContext是action和web容器之间的桥梁。
ActionContext作为action的数据环境,它是一个容器,相当于一个Map,保存有针对某个请求的详细信息,同时应保证线程安全。
示例如下:
public String scope() throws Exception{
ActionContext ctx = ActionContext.getContext();
ctx.getApplication().put("app", "应用范围");//往ServletContext里放入app
ctx.getSession().put("ses", "session范围");//往session里放入ses
ctx.put("req", "request范围");//往request里放入req
return "scope";
}
JSP:
<body>
${applicationScope.app}<br>
${sessionScope.ses}<br>
${requestScope.req}<br>
</body>
实际上Struts2底层把ServletContext对象和HttpSession对象封装成Map对象,从而将Servlet API从Action中分离出来。
ActionContext ctx = ActionContext.getContext();
//获得Session
Map session = ctx.getSession();
//获得Application
Map application = ctx.getApplication();
2. ServletActionContext
这个类直接继承了ActionContext,与ActionContex把Req封装Map不同,它提供了直接与Servlet相关对象访问的功能。
public class XAction{
private HttpServletRequest req;
//下面这条语句放在这个位置是错误的,同样把这条语句放在构造方法中也是错误的。
//private HttpServletRequest req = ServletActionContext.getRequest();
public String execute(){
req = ServletActionContext.getRequest();
HttpSession session = req.getSession();
}
}
注意事项,能用ActionContext就不要用ServletActionContext。
对于上述注释,原因为,两者都为线程安全,线程安全要求每个线程都独立进行,所以req的创建也要独立进行。所以这句话不要放在构造函数中,也不要直接放在类中,而应该放在具体的方法体中。
3. 通过拦截器注入
public class XAction extends ActionSupport implements SessionAware, ServletRequestAware, ServletResponseAware {
private HttpServletRequest request;
private HttpServletResponse response;
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
public void setServletResponse(HttpServletResponse response) {
this.response = response;
}
public String execute() {
HttpSession session = request.getSession();
return SUCCESS;
}
}