拦截器:
package com.interceptor;
public class Interceptor
{
public void before()
{
System.out.println("before");
}
public void after()
{
System.out.println("after");
}
}
反射机制或处理类
package com.interceptor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyHandler implements InvocationHandler
{
//定义目标对象
private Object object;
//声明拦截器对象
private Interceptor interceptor = new Interceptor();
//定义目标对象设置
public void setObject(Object object)
{
this.object = object;
}
/**
* invoke是真正执行的方法
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable
{
Object result = null;
interceptor.before();
result = method.invoke(object, args);//目标方法
interceptor.after();
return result;
}
}
代理类,最终是通过代理类来处理的
package com.interceptor;
import java.lang.reflect.Proxy;
/**
* 用于产生代理
* @author 向先函
*
*/
public class MyProxy
{
//传入的是目标对象
public Object getProxy(Object object)
{
MyHandler myHandler = new MyHandler();
myHandler.setObject(object);
//返回新的代理,第一个参数是类的装载器,第二个参数是实现的接口,第三个参数是处理的实例
return Proxy.newProxyInstance(Target.class.getClassLoader(), object
.getClass().getInterfaces(), myHandler);
}
}
测试类:
package com.interceptor;
public class Client
{
public static void main(String[] args)
{
//目标对象,或被拦截的对象
TargetInterface target = new Target();
MyProxy myProxy = new MyProxy();
//生成代理代理目标对象
TargetInterface proxy = (TargetInterface)myProxy.getProxy(target);
proxy.doSomething();
}
}
Struts拦截器(主要用来拦截action)
建立拦截器
package com.test.interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
public class MyInterceptor implements Interceptor
{
public void destroy()
{
System.out.println("destroy");
}
public void init()
{
System.out.println("init");
}
public String intercept(ActionInvocation invocation) throws Exception
{
System.out.println("intercept");
String result = invocation.invoke();
System.out.println("finish");
return result;
}
}
配置struts.xml
<interceptors>
<!-- 定义拦截器 -->
<interceptor name="myInterceptor" class="com.test.interceptor.MyInterceptor">
<param name="hello">world</param>
</interceptor>
</interceptors>
<action name="register" class="com.test.action.RegisterAction" method="test">
<result name="success">/success.jsp</result>
<result name="input">/register2.jsp</result>
<!-- 应用拦截器 -->
<interceptor-ref name="myInterceptor">
</interceptor-ref>
</action>
Struts2的核心是拦截器
以上代码运行拦截成功,但默认拦截器就不起作用了。原因是:如果手工增加拦截器,系统不会将默认的拦截器附加到它上面。
解决办法,用手工的方法再重新导入一次
<action name="register" class="com.test.action.RegisterAction" method="test">
<result name="success">/success.jsp</result>
<result name="input">/register2.jsp</result>
<!-- 应用拦截器 -->
<interceptor-ref name="myInterceptor3"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
拦截器增加参数
1在定义拦截器的时候使用
Struts.xml
<!-- 定义拦截器 -->
<interceptor name="myInterceptor" class="com.test.interceptor.MyInterceptor">
<param name="hello">world</param>
</interceptor>
2在使用的时候定义,同时使用时的定义会覆盖点定义时使用的变量
<action name="register" class="com.test.action.RegisterAction" method="test">
<result name="success">/success.jsp</result>
<result name="input">/register2.jsp</result>
<!-- 应用拦截器 -->
<interceptor-ref name="myInterceptor">
<param name="hello">welcome</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
结果显示welcome。
MyInterceptor拦截类
public class MyInterceptor implements Interceptor
{
//增加和name相同的名称的属性并增加GETSET方法
private String hello;
-----增加GETSET方法---------
public void destroy()
{
System.out.println("destroy");
}
public void init()
{
System.out.println("init");
System.out.println(hello);
}
public String intercept(ActionInvocation invocation) throws Exception
{
System.out.println("intercept");
String result = invocation.invoke();
System.out.println("finish");
return result;
}
}
自定义拦截器栈
<interceptors>
<!-- 定义拦截器 -->
<interceptor name="myInterceptor"class="com.test.interceptor.MyInterceptor">
<param name="hello">world</param>
</interceptor>
<!-- 定义拦截器栈 -->
<interceptor-stack name="myStack">
<interceptor-ref name="myInterceptor"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<action name="register" class="com.test.action.RegisterAction" method="test">
<result name="success">/success.jsp</result>
<result name="input">/register2.jsp</result>
<!-- 应用拦截器 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
改变默认拦截器
//在包下定义默认的拦截器,会应用到说有的action中,但如果action中定义了自己的拦截器则默认拦截器就对它不起作用了:
<interceptor name="myInterceptor"class="com.test.interceptor.MyInterceptor">
<param name="hello">world</param>
</interceptor>
<!-- 定义拦截器栈 -->
<interceptor-stack name="myStack">
<interceptor-ref name="myInterceptor"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
//定义默认拦截器
<default-interceptor-ref name="myStack"></default-interceptor-ref>
<action name="register" class="com.test.action.RegisterAction" method="test">
<result name="success">/success.jsp</result>
<result name="input">/register2.jsp</result>
<!-- 应用拦截器 -->
</action>
简化拦截器只实现主要的:
public class MyInterceptor2 extends AbstractInterceptor
{
@Override
public String intercept(ActionInvocation invocation) throws Exception
{
System.out.println("intercept2");
String result = invocation.invoke();
System.out.println("finish2");
return result;
}
}
拦截器的顺序和栈执行的先后有关:回来的顺序和执行的顺序相反
<interceptor-stack name="myStack">
<interceptor-ref name="myInterceptor"></interceptor-ref>
<interceptor-ref name="myInterceptor2"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
方法过滤拦截器
public class MyInterceptor3 extends MethodFilterInterceptor
{
@Override
protected String doIntercept(ActionInvocation invocation) throws Exception
{
System.out.println("my interceptor3");
String result = invocation.invoke();
return result;
}
}
配置包含谁和拦截谁struts.xml
<struts>
<constant name="struts.custom.i18n.resources" value="message"></constant>
<package name="struts2" extends="struts-default">
<interceptors>
<interceptor name="myInterceptor3" class="com.test.interceptor.MyInterceptor3">
</interceptor>
<!-- 定义拦截器栈 -->
<interceptor-stack name="myStack">
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="myStack"></default-interceptor-ref>
<action name="register" class="com.test.action.RegisterAction" method="test">
<result name="success">/success.jsp</result>
<result name="input">/register2.jsp</result>
<!-- 应用拦截器 拦截谁不拦截谁,只要include包含的都被执行,优先级高à
<interceptor-ref name="myInterceptor3">
<param name="excludeMethods">test,execute</param>
<param name="includeMethods">test</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
</package>
</struts>
监听器PreResultListener接口,用于执行excuse之后,在转到JSP页面之前被调用。
建立监听器
/**
* 监听类
* @author 向先函
*
*/
public class MyListener implements PreResultListener
{
//resultCode是结果如input不成功,success表示成功等
public void beforeResult(ActionInvocation invocation, String resultCode)
{
System.out.println("result : " + resultCode);
}
}
注册到拦截器
public class MyInterceptor3 extends MethodFilterInterceptor
{
@Override
protected String doIntercept(ActionInvocation invocation) throws Exception
{
//注册监听器,只要把实例加进去就行
invocation.addPreResultListener(new MyListener());
System.out.println("my interceptor3");
String result = invocation.invoke();
System.out.println("after my interceptor3 finished");
return result;
}
}
程序综合,登录提交:解决非法访问
新建拦截器:
package com.test.interceptor;
import java.util.Map;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
public class AuthInterceptor extends AbstractInterceptor
{
@Override
@SuppressWarnings("unchecked")
public String intercept(ActionInvocation invocation) throws Exception
{
//Session 已经被放到容器里边了
Map map = invocation.getInvocationContext().getSession();
if(map.get("user") == null)
{
return Action.LOGIN;
}
else
{
return invocation.invoke();
}
}
}
配置Action.LOGIN
<!-- 全局login重定向 -->
<global-results>
<result name="login" type="redirect">/login2.jsp</result>
</global-results>
处理LOGINaCTION类
public class LoginAction extends ActionSupport
{ @SuppressWarnings("unchecked")
public String execute() throws Exception
{
if ("hello".equals(this.getUsername().trim())
&& "world".equals(this.getPassword().trim()))
{
Map map = ActionContext.getContext().getSession();
map.put("user","valid");
return "success";
}
else
{
this.addFieldError("username", "username or password error");
return "failer";
}
}
注册拦截器:
<!-- 定义拦截器栈 -->
<interceptor name="auth" class="com.test.interceptor.AuthInterceptor">
</interceptor>