攔截器:
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>