原文来自搬砖工,如需转载请注明出处
博主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。因为拦截器在自定义的时候更需要从业务逻辑上来判断什么时候使用拦截器来出来某些特定逻辑。希望上面的例子能帮助大家理解拦截器