原文來自搬磚工,如需轉載請註明出處
博主SSH框架專欄請戳這裏http://blog.csdn.net/column/details/14227.html
一、攔截器的設計思想
攔截器是Struts2中重要的組成部分,可以把Action認爲是一個空的容器,通過攔截器實現了Struts2的大部分通用功能。例如params攔截器將請求參數解析,並設置成Action的屬性。servlet-config攔截器將HTTP請求中的HttpServletRequest和HttpServletResponse對象傳遞給Action對象等。
攔截器的設計思想是當前比較流行的AOP面向方面編程思想的應用,其實現模式是代理模式和反射機制。關於代理模式和反射機制資料點擊
二、如何自定義攔截器
1.自定義攔截器如何起攔截作用?
經過如下步驟,自定義攔截器在Action之前,默認攔截器之後進行攔截操作。主要就是處理一些業務邏輯
a)Web瀏覽器發送請求
b)首先通過一組Struts2默認的攔截棧 dispatcher (或者 ServletFilter)
c)定義interceptor(攔截器)
d)Action
e)Result
2.如何定義一個攔截器
a)創建一個Action,繼承AbstractInterceptor類並且實現intercept方法。
b)在intercept中處理某些邏輯
c)配置攔截器
三、攔截器配置示例
下面講一個小例子,在與用戶登陸相關的頁面,當用戶登陸一段時間我們就會清空session,那麼就需要用戶重新登陸。admin.jsp是用戶已經登陸的後臺管理頁面,當過一段時間之後,後臺清空session。這時候就需要用戶重新登陸,就會跳轉到登陸頁面重新登陸。(博主的例子沒有添加跳轉url,大家可以自行設計)
首先創建一個登陸頁面login.jsp
<%@ page language="java" import="java.util.*" pageEncoding="gbk"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
${tips}
<form id="login" name="login" action="/login.action" method="post">
<table border="0">
<tr>
<td>name:</td>
<td><input type="text" name="username" id="username"/></td>
</tr>
<tr>
<td>password:</td>
<td><input type="password" name="password" id="password"/></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="login"/></td>
</tr>
</table>
</form>
</body>
</html>
一個登陸成功頁面Success.jsp
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
</head>
<body>
hello world!,${username}
</body>
</html>
後臺管理頁面admin.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
</head>
<body>
<a href="<%=path%>/admin.action">後臺管理<a/>
</body>
</html>
然後定義一個登陸LoginAction,登陸成功就跳轉成功頁面。用戶名密碼都爲admin
package com.study.action;
import java.util.Map;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class LoginAction extends ActionSupport{
private String username;
private String password;
private String tips;
public String execute() throws Exception {
if(username.equals("admin")&&password.equals("admin")){
ActionContext ac = ActionContext.getContext();
Map session = ac.getSession();
session.put("username", username);
return SUCCESS;
}else{
tips = "用戶名或密碼錯誤!";
return INPUT;
}
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getTips() {
return tips;
}
public void setTips(String tips) {
this.tips = tips;
}
}
定義一個後臺管理AdminAction,只負責簡單的頁面轉發
package com.study.action;
import com.opensymphony.xwork2.ActionSupport;
public class AdminAction extends ActionSupport{
public String execute() throws Exception {
return "admin";
}
}
定義一個攔截器AdminInterceptor,驗證管理頁面是否是爲admin用戶,並且已經登陸
package com.study.interceptor;
import java.util.Map;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
public class AdminInterceptor extends AbstractInterceptor{
public String intercept(ActionInvocation ai) throws Exception {
ActionContext ac = ai.getInvocationContext();
Map session = ac.getSession();
String username = (String) session.get("username");
if(username!=null&&username.equals("admin")){
return ai.invoke();
}else{
String tips = "請先使用管理員身份登錄!";
session.put("tips", tips);
return Action.INPUT;
}
}
}
最後就是配置我們的自定義攔截器,注意,重點是不要覆蓋默認攔截器
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<package name="example" namespace="/" extends="struts-default">
<interceptors>
<interceptor name="admininterceptor" class="com.study.interceptor.AdminInterceptor"></interceptor>
</interceptors>
<action name="login" class="com.study.action.LoginAction">
<result name="success">/Success.jsp</result>
<result name="input">/login.jsp</result>
</action>
<action name="admin" class="com.study.action.AdminAction">
<result name="admin">/admin.jsp</result>
<result name="input">/login.jsp</result>
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="admininterceptor"></interceptor-ref>
</action>
</package>
</struts>
ps:博主舉的例子不具有很普遍的意義,對於攔截器應當具有更通用的攔截意義,比如參數攔截器就把參數處理之後賦給了我們的Action。因爲攔截器在自定義的時候更需要從業務邏輯上來判斷什麼時候使用攔截器來出來某些特定邏輯。希望上面的例子能幫助大家理解攔截器