struts2中已经给我们写好了很多的拦截器,但是,终归是不够的,有些拦截器达到不了我们的要求,这样,我们必须自己写一个拦截器。
在开始着手创建自定义拦截器前,切记以下原则:
拦截器必须是无状态的,不要使用在API提供的ActionInvocation之外的任何东西。
要求拦截器是无状态的原因是Struts 2不能保证为每一个请求或者action创建一个实例,所以如果拦截器带有状态,会引发并发问题。
所有的Struts 2的拦截器都直接或间接实现接口com.opensymphony.xwork2.interceptor.Interceptor。除此之外,大家可能更喜欢继承类com.opensymphony.xwork2.interceptor.AbstractInterceptor。
首先,创建授权拦截器类struts2.AuthorizationInterceptor,代码如下:
package struts2;
import java.util.Map;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
/**
*
* @author 朱湘鄂
* @version 1.0
* @date 2010-11-27
*/
@SuppressWarnings("serial")
public class AuthorizationInterceptor extends AbstractInterceptor{
@Override
public String intercept(ActionInvocation ai) throws Exception {
Map session = ai.getInvocationContext().getSession();
String role = (String) session.get( " ROLE " );
if ( null != role) {
Object o = ai.getAction();
if (o instanceof RoleAware) {
RoleAware action = (RoleAware) o;
action.setRole(role);
}
return ai.invoke();//继续执行下面的操作
} else {
return Action.LOGIN;//转向登录页面。
}
}
}
我们通过检查session是否存在键为“ROLE”的字符串,判断用户是否登陆。如果用户已经登陆,将角色放到Action中,调用Action;否则,拦截直接返回Action.LOGIN字段。为了方便将角色放入Action,我定义了接口strtus2.RoleAware,代码如下:
package struts2;
public interface RoleAware {
public void setRole(String role);
}
接着,创建Action类struts2.AuthorizatedAccess模拟访问受限资源,它作用就是通过实现RoleAware获取角色,并将其显示到showUser.jsp中,代码如下:
package struts2;
import com.opensymphony.xwork2.ActionSupport;
@SuppressWarnings("serial")
public class AuthorizatedAccess extends ActionSupport implements RoleAware{
private String role;
public String getRole() {
return role;
}
public void setRole(String role) {
}
public String execute(){
return SUCCESS;
}
}
showUser.jsp代码如下
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<s:set name="role" value="roles.role"></s:set>
<h1> 你的角色是: <s:property value ="role" /></h1 >
</body>
</html>
然后,创建struts2.Roles初始化角色列表,代码如下:
package struts2;
import java.util.Hashtable;
import java.util.Map;
public class Roles {
public Map < String, String > getRoles() {
Map < String, String > roles = new Hashtable < String, String > ( 2 );
roles.put( " EMPLOYEE " , " Employee " );
roles.put( " MANAGER " , " Manager " );
return roles;
}
}
接下来,新建Login.jsp实例化struts2.Roles,并将其roles属性赋予<s:radio>标志,代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1> 登录 </h1 >
请选择你的角色:
<s:bean id ="roles" name ="struts2.Roles" />
<s:form action ="Login" >
<s:radio list ="#roles.roles" value ="'EMPLOYEE'" name ="role" label ="Role" />
<s:submit/>
</s:form >
</body>
</html>
创建Action类struts2.Login将role放到session中,并转到Action类struts2.AuthorizatedAccess,代码如下:
package struts2;
import java.util.Map;
import org.apache.struts2.interceptor.SessionAware;
import com.opensymphony.xwork2.ActionSupport;
@SuppressWarnings("serial")
public class Login extends ActionSupport implements SessionAware {
private String role;
private Map session;
public String getRole() {
return role;
}
public void setRole(String role) {
this .role = role;
}
public void setSession(Map session) {
this .session = session;
}
@Override
public String execute() {
session.put( "ROLE" , role);
return SUCCESS;
}
}
最后,配置struts.xml文件,内容如下:
<!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 ="struts2" extends ="struts-default" >
<interceptors >
<interceptor name ="auth" class ="struts2.AuthorizationInterceptor" />
</interceptors >
<action name ="Login" class ="struts2.Login" >
<result type ="chain"> AuthorizatedAccess </result >
</action >
<action name ="AuthorizatedAccess" class ="struts2.AuthorizatedAccess" >
<interceptor-ref name ="auth" />
<result name ="login" > /login.jsp </result >
<result name ="success" > /showUser.jsp </result >
</action >
</package >
</struts>