Struts2种的Interceptor类似于以往我们知道的过滤器,对用户的请求进行过滤处理,根据过滤得情况决定下一步需要采取的操作。
也可以理解成对用户的请求进行拦截处理。而且可以将多个拦截器合在一起使用,进行多种工作的拦截处理。
同样可以理解成Spring中的AOP,对一些操作进行额外的处理(比如前置处理、后置处理等)
Struts2种预定义了多种拦截器,比如Timer拦截器负责处理Action的运行时间,Log拦截器负责进行日志记录。在这里不对预定义的拦截器进行讲解。
我们同样可以定义我们自己的拦截器,对某些操作进行通用的处理。比如通用的验证处理。当我们请求某些操作的时候需要事先已经进行了验证,否则不允许请求这些操作,如果进行了验证,则允许。那么我们就可以自定义一个验证的拦截器,对需要进行验证的操作进行拦截。
好了,下面通过一个简单的实例进行讲解。
创建一个web project,比如这里是MySampleWeb,当然需要加入Struts所需要的类库(.jar)
首先创建拦截器类LoginInterceptor,需要继承AbstractInterceptor,这样,我们 就建立了一个我们自定义的拦截器。拦截器中存在一个名称为intercept的方法,这个方法即为拦截方法,这个方法为契约方法,当拦截器运行的时候,此 方法负责处理拦截,我们的拦截代码写在其中。
因为此拦截器负责判断是否验证的拦截,具体的代码如下:
package com.frank.interceptor;
import java.util.Map;
import com.frank.action.UserAware;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
public class LoginInterceptor extends AbstractInterceptor {
@Override
public String intercept(ActionInvocation ai) throws Exception {
Map session=ai.getInvocationContext().getSession();//得到当前的session
String username=(String)session.get("username");//取得当前session中的username属性
if(username!=null){//如果存在代表已经登录过
Object user=ai.getAction();
if(user instanceof UserAware){//如果此Action需要username属性值,则将值记录到Action中
UserAware action=(UserAware)user;
action.setUsername(username);
}
return ai.invoke();//正常执行此Action
}else{
return Action.LOGIN;//没有登录过,则转发到登录页面
}
}
}
下面建立UserAware接口,注意实现此接口的Action代表需要username的内容,此接口只有一个设置username的方法
package com.frank.action;
public interface UserAware {
public void setUsername(String username);
}
下面建立需要被拦截的Action,在这里建立一个名称为ShowUserAction,此Action需要记录username,所以额外需要实现UserAware接口,代码如下:
package com.frank.action;
import com.opensymphony.xwork2.ActionSupport;
public class ShowUserAction extends ActionSupport implements UserAware {
private String username;
public void setUsername(String username) {
this.username=username;
}
public String getUsername() {
return username;
}
@Override
public String execute() throws Exception {
return SUCCESS;
}
}
此Action非常的简单,而且契约方法execute只是简单的返回SUCCESS,注意此Action需要记录username,以便转发到jsp时,可以将username的内容传出,由相应的jsp使用
好了,现在建立登录Action,以便处理登录的请求,名称为LoginAction,和其他的登录Action一 样,负责进行登录验证工作,验证工作交给javabean去做(可以按照自己的需要进行实际的验证处理),因为验证成功后需要将username保存到 session中,所以在此Action实现SessionAware接口以便使用session。session为Map类型,所以声明一个Map类型 的成员session,并实现setSession方法得到session,代码如下:
package com.frank.action;
import java.util.Map;
import org.apache.struts2.interceptor.SessionAware;
import com.frank.rule.UserBean;
import com.opensymphony.xwork2.ActionSupport;
public class LoginAction extends ActionSupport implements SessionAware {
private Map session;
private String username;
private String password;
public void setSession(Map session) {
this.session=session;
}
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;
}
@Override
public String execute() throws Exception {
UserBean userBean=new UserBean();
userBean.setUsername(username);
userBean.setPassword(password);
if(userBean.checkUser()){
session.put("username", username);
return SUCCESS;
}else{
return INPUT;
}
}
}
建立UserBean,进行实际的验证工作,在此,如果输入的用户名为admin、guest、frank任意一个都为正确,忽略密码。实际的验证工作可以自己定义
package com.frank.rule;
public class UserBean {
private String username;
private String password;
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 boolean checkUser(){
if(this.username.equals("admin")||this.username.equals("guest")||this.username.equals("frank")){
return true;
}
return false;
}
}
创建登录页面login.jsp,非常的简单:
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'login.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<h1>User Login</h1>
<form action="login.action">
<s:textfield name="username" label="Username:"/><br>
<s:password name="password" label="Password:"/><br>
<s:submit/>
</form>
</body>
</html>
建立显示用户信息的页面showUsername.jsp
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'showUsername.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<h1>The Username:<s:property value="username"/></h1>
</body>
</html>
好了现在进行必须的配置工作,首先配置web.xml,以便可以使用struts2,配置如下:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
strtus.xml配置文件如下,注意拦截器的配置,拦截器负责拦截ShowUserAction
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd" > <struts> <include file="struts-default.xml"/> <package name="default" extends="struts-default"> <interceptors> <interceptor name="loginInteceptor" class="com.frank.interceptor.LoginInterceptor"/> </interceptors> <action name="login" class="com.frank.action.LoginAction"> <result type="chain">showUserAction</result> </action> <action name="showUserAction" class="com.frank.action.ShowUserAction"> <interceptor-ref name="loginInteceptor"/> <result name="login">login.jsp</result> <result>showUsername.jsp</result> </action> </package> </struts>
部署运行
请求showUserAction,拦截器拦截,因为开始时候没有登录,所以转发到login.jsp页面,如下图:
用正确的密码登录,显示如下:
如果此时在此请求showUserAction,则不需要登录,因为已经登录过了