1. Struts架构图
a) 见文档
2. Struts执行过程分析
3. Interceptor拦截器过程模拟
4. 定义自己的拦截器
a) acegi – spring security
5. 使用token拦截器控制重复提交(很少用)
6. 类型转换
a) 默认转换
i. 日期处理
b) 写自己的转换器:
public class MyPointConverter extends DefaultTypeConverter{
@Override
public Object convertValue(Object value, Class toType) {
if(toType == Point.class) {
Point p = new Point();
String[] strs = (String[])value;
String[] xy = strs[0].split(",");
p.x = Integer.parseInt(xy[0]);
p.y = Integer.parseInt(xy[1]);
return p;
}
if(toType == String.class) {
return value.toString();
}
return super.convertValue(value, toType);
}
}
public class MyPointConverter extends StrutsTypeConverter{
@Override
public Object convertFromString(Map context, String[] values, Class toClass) {
Point p = new Point();
String[] strs = (String[])values;
String[] xy = strs[0].split(",");
p.x = Integer.parseInt(xy[0]);
p.y = Integer.parseInt(xy[1]);
return p;
}
@Override
public String convertToString(Map context, Object o) {
// TODO Auto-generated method stub
return o.toString();
}
}
c) 三种注册方式:
i. 局部:XXXAction-conversion.properties
1. p(属性名称) = converter
ii. 全局:xwork-conversion.properties
1. com.xxx.XXX(类名)= converter
iii. Annotation
d) 如果遇到非常麻烦的映射转换
i. request.setAttribute();
ii. session
_________________________________________________________________________
interceptor 流程图
package com.demo; public interface Interceptor { public void intercept(ActionInvocation invocation) ; }
package com.demo; public class FirstInterceptor implements Interceptor { public void intercept(ActionInvocation invocation) { System.out.println(1); invocation.invoke(); System.out.println(-1); } }
package com.demo; public class SecondtInterceptor implements Interceptor { public void intercept(ActionInvocation invocation) { System.out.println(1); invocation.invoke(); System.out.println(-2); } }
package com.demo; import freemarker.template.utility.Execute; public class Action { public void execute() { System.out.println("execute"); } }
package com.demo; import java.util.ArrayList; import java.util.List; public class ActionInvocation { List<Interceptor> interceptors = new ArrayList<Interceptor>(); int index = -1; Action a = new Action(); public ActionInvocation() { this.interceptors.add(new FirstInterceptor()); this.interceptors.add(new SecondtInterceptor()); } public void invoke() { index ++ ; if(index >= this.interceptors.size()) { a.execute(); } else { this.interceptors.get(index).intercept(this); } } }
package com.demo; public class Main { public static void main(String[] args) { new ActionInvocation().invoke(); } }
防止用户刷新在数据库留下的user 的机制 提交方式设置post 会进行提示,要确认才重新发送 <form action="user" method="post"> <s:token></s:token> 生成一个随机数
value="6ZLIK012XOVVYKHFM21BR6CAW3R78TDN" <input type="hidden" name="struts.token.name" value="struts.token" /> <input type="hidden" name="struts.token" value="6ZLIK012XOVVYKHFM21BR6CAW3R78TDN" /> No result defined for action com.demo.action.UserAction and result invalid.token 经过如下设置可以杜绝重复提交 <interceptor-ref name="defaultStack"/> <interceptor-ref name="token"/> // 检查session里面记录的用户是否存在 <result name="invalid.token">/error.jsp</result> 整个例子代码如下: package com.demo.action; import com.opensymphony.xwork2.ActionSupport; public class UserAction extends ActionSupport { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String execute() throws Exception { System.out.println("a user added"); return super.execute(); } } package com.demo.action; import com.opensymphony.xwork2.ActionSupport; public class InputAction extends ActionSupport { @Override public String execute() throws Exception { return super.execute(); } } <!-- struts.xml --> <struts> <constant name="struts.devMode" value="true"/> <package name="resultType" extends="struts-default" namespace="/"> <action name="input" class="com.demo.action.InputAction"> <result>/input.jsp</result> </action> <action name="user" class="com.demo.action.UserAction"> <result>/addOK.jsp</result> <interceptor-ref name="defaultStack"/> <interceptor-ref name="token"/> <result name="invalid.token">/error.jsp</result> </action> </package> </struts>
<!-- input.jsp --> <body> <form action="user" method="post"> name: <input name="name"> age: <input name="age"> <input type="submit" value="add"> <s:token></s:token> </body>
<!-- addOK.jsp --> <body> addOK </body>
<!-- error.jsp --> <body> 严谨重复的事! <br/> </body>
容器接收参数一定要用泛型,要不会出现很多问题
HTTP 里面进行传参数永远是string 类型
http://localhost:8080/Struts2_37_type_conversion/test?name=dd&age=9&date=2011-11-18%2005:26:55&set=English name: dd age: 9 date: 11-11-18 2011/11/18 05:26:55 [English] http://localhost:8080/Struts2_37_type_conversion/test?userMap[%27a%27]=userA&userMap[%27b%27]=userB {b=userB, a=userA} http://localhost:8080/Struts2_37_type_conversion/test?p=3,3 java.awt.Point[x=3,y=3] http://localhost:8080/Struts2_37_type_conversion/test?pointMap[%27a%27]=7,3&%20pointMap[%27b%27]=3,5 pointMap: {b=java.awt.Point[x=3,y=5], a=java.awt.Point[x=7,y=3]} http://localhost:8080/Struts2_37_type_conversion/test?pointList[0].x=8&pointList[0].y=9 [java.awt.Point[x=8,y=9]]
package com.demo.action; import java.awt.Point; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Set; import com.opensymphony.xwork2.ActionSupport; public class TestAction extends ActionSupport { private String name; private int age; private Date date; Set<String> set; Map<String, String> userMap; Point p; List<Point> pointList; Map<String, Point> pointMap; @Override public String execute() throws Exception { return super.execute(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public Set<String> getSet() { return set; } public void setSet(Set<String> set) { this.set = set; } public Map<String, String> getUserMap() { return userMap; } public void setUserMap(Map<String, String> userMap) { this.userMap = userMap; } public List<Point> getPointList() { return pointList; } public void setPointList(List<Point> pointList) { this.pointList = pointList; } public Map<String, Point> getPointMap() { return pointMap; } public void setPointMap(Map<String, Point> pointMap) { this.pointMap = pointMap; } public Point getP() { return p; } public void setP(Point p) { this.p = p; } }
package com.demo.converter; import java.awt.Point; import java.util.Map; import org.apache.struts2.util.StrutsTypeConverter; import com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter; //StrutsTypeConverter extends DefaultTypeConverter /* public class MyPointConverter extends StrutsTypeConverter{ @Override public Object convertFromString(Map context, String[] values, Class toClass) { //convertFromString 从字符串转成Point类型 Point p = new Point(); String[] strs = (String [])values; String[] xy = strs[0].split(","); p.x = Integer.parseInt(xy[0]); p.y = Integer.parseInt(xy[1]); return p; } @Override public String convertToString(Map context, Object o) { //convertToString 从Point类型转成字符串 return o.toString(); } } */ public class MyPointConverter extends DefaultTypeConverter { @Override public Object convertValue(Object value, Class toType) { if(toType == Point.class) { Point p = new Point(); String[] strs = (String[])value; String[] xy = strs[0].split(","); p.x = Integer.parseInt(xy[0]); p.y = Integer.parseInt(xy[1]); return p; } if(toType == String.class) { return value.toString(); } return super.convertValue(value, toType); } }
<!-- struts.xml --> <struts> <constant name="struts.devMode" value="true"/> <package name="test" extends="struts-default" namespace="/"> <action name="test" class="com.demo.action.TestAction"> <result>/test.jsp</result> </action> </package> </struts>
<!-- test.jsp --> <%@ page language="java" import="java.util.*" pageEncoding="GB18030"%> <%@taglib uri="/struts-tags" prefix="s"%> <html> <head> </head> <body> name: <s:property value="name"/><br/> age: <s:property value="age"/><br/> date: <s:property value="date"/><br/> <s:date name="date" format="yyyy/MM/dd HH:mm:ss"/><br/> <s:property value="set"/><br/> <s:property value="userMap"/><br/> <s:property value="p"/><br/> <s:property value="pointList"/><br/> pointMap: <s:property value="pointMap"/><br/> </body> </html>
TestAction-conversion.properties p=com.demo.converter.MyPointConverter action包下的 xwork-conversion.properties java.awt.Point=com.demo.converter.MyPointConverter src目录下的 全局的
1. Lambda表达式
2. 验证框架
3. UI标签
4. 类型转换中的异常处理
5. 上传与下载文件
6. Struts2注解
1. Action
a) namespace(掌握)
b) path(掌握)
c) DMI(掌握)
d) wildcard(掌握)
e) 接收参数(掌握前两种)
f) 访问request等(掌握Map IOC方式)
g) 简单数据验证(掌握addFieldError和<s:fieldError)
2. Result
a) 结果类型(掌握四种,重点两种)
b) 全局结果(掌握)
c) 动态结果(了解)
3. OGNL表达式(精通)
a) # % $
4. Struts标签
a) 掌握常用的
5. 声明式异常处理(了解)
6. I18N(了解)
7. CRUD的过程(最重要是设计与规划)(精通)
8. Interceptor的原理(掌握)
9. 类型转换(掌握默认,了解自定义)