struts2.1.6 interceptor 09

Struts拦截器以及源码解析

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 流程图

struts2.1.6 interceptor 09_第1张图片




struts2.1.6 interceptor 09_第2张图片


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注解

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. 类型转换(掌握默认,了解自定义)






你可能感兴趣的:(String,struts,object,Interceptor,Class,action)