一. 拦截器的基本概念和基本用法
要创建一个拦截器,可以继承AbstractInterceptor类:
public class SimpleInterceptor extends AbstractInterceptor {
private static final long serialVersionUID = 1L;
@Override
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("开始执行我的拦截器");
// ActionInvocation的invoke方法负责调用下一个拦截器的方法或指定的Action当中指定的方法
String result = invocation.invoke();
System.out.println("结束始执行我的拦截器");
return result;
}
}
其中result保存的是Aciton中方法执行的返回值。
然后在struts配置:
<package name="basicstruts2" extends="struts-default"
namespace="/test">
<interceptors>
<interceptor name="SimpleInterceptor"
class="com.thr.struts2.interceptor.SimpleInterceptor"></interceptor>
<interceptor name="SimpleInterceptor2"
class="com.thr.struts2.interceptor.SimpleInterceptor2"></interceptor>
<interceptor name="SimpleInterceptor3"
class="com.thr.struts2.interceptor.SimpleInterceptor3"></interceptor>
</interceptors>
<action name="user" class="com.thr.struts2.action.UserAction">
<interceptor-ref name="SimpleInterceptor" />
<interceptor-ref name="SimpleInterceptor2" />
<interceptor-ref name="SimpleInterceptor3" />
<result name="add_input">/add_input.jsp</result>
<result name="add_success">/add_success.jsp</result>
<result>/success.jsp</result>
<result name="list">/list.jsp</result>
<result name="static">/methodcalls.jsp</result>
</action>
</package>
就可以了,我们这里配置了3个拦截器,然后随便调用Action的一个方法,3个拦截器和Action方法的调用顺序是:
依次进入每一个拦截器的intercept方法(1->2->3),在执行invocation.invoke()方法前,调用action方法,最后执行完intercept方法(3->2->1)。
二. 拦截器栈的作用和配置用法
当拦截器比较多的时候我们可以统一添加到拦截器栈里面然后统一添加到Action当中,例如我们有一个LoginInterceptor来检测用户名和密码是否输入正确:
public class LoginInterceptor extends AbstractInterceptor {
@Override
public String intercept(ActionInvocation invocation) throws Exception {
UserAction action = (UserAction) invocation.getAction();
// ActionProxy proxy = invocation.getProxy();
String result = null;
if (!("Jerry".equals(action.getUsername()) && "111".equals(action
.getPassword()))) {
return "login";
}
result = invocation.invoke();
return result;
}
}
struts配置如下:
<package name="basicstruts2" extends="struts-default"
namespace="/test">
<interceptors>
<interceptor name="SimpleInterceptor"
class="com.thr.struts2.interceptor.SimpleInterceptor"></interceptor>
<interceptor name="SimpleInterceptor2"
class="com.thr.struts2.interceptor.SimpleInterceptor2"></interceptor>
<interceptor name="SimpleInterceptor3"
class="com.thr.struts2.interceptor.SimpleInterceptor3"></interceptor>
<interceptor name="LoginInterceptor"
class="com.thr.struts2.interceptor.LoginInterceptor"></interceptor>
<interceptor-stack name="myStack">
<interceptor-ref name="defaultStack" />
<interceptor-ref name="LoginInterceptor" />
<interceptor-ref name="SimpleInterceptor" />
<interceptor-ref name="SimpleInterceptor2" />
<interceptor-ref name="SimpleInterceptor3" />
</interceptor-stack>
</interceptors>
<action name="user" class="com.thr.struts2.action.UserAction">
<interceptor-ref name="myStack" />
<result name="add_input">/add_input.jsp</result>
<result name="add_success">/add_success.jsp</result>
<result>/success.jsp</result>
<result name="list">/list.jsp</result>
<result name="static">/methodcalls.jsp</result>
<result name="login">/add_input.jsp</result>
</action>
</package>
这里我们在上面定义了一个myStack的拦截器栈,里面放入了一个默认的defaultStack和我们自定义的4个拦截器,在action标签内,使用interceptor-ref来引用这个拦截器栈。其中这个defaultStack是系统默认如果我们没有指定拦截器就会给我们的一个拦截器,当我们在action当中添加了拦截器之后,系统就不会给我们这个拦截器,所以这里需要将defaultStack添加到我们的拦截器栈中,统一加入Action当中。
修改一下之前我们创建的add_input.jsp文件:
UserName:<input name="username" /><br />
Password:<input name="password" type="password" /><br />
加入这两个input域就可以实现登陆的验证了。
三. 拦截器常用配置技巧和全局结果集GlobalResult
接下来实现一个比较有实际应用的登陆验证。
首先创建一个LoginAction:
package com.thr.struts2.action;
import com.opensymphony.xwork2.ActionContext;
public class LoginAction {
private String username;
private String password;
public String login() {
if ("Jerry".equals(username) && "123".equals(password)) {
ActionContext.getContext().getSession().put("username", username);
return "success";
}
return "login";
}
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 class LoginInterceptor extends AbstractInterceptor {
@Override
public String intercept(ActionInvocation invocation) throws Exception {
// UserAction action = (UserAction) invocation.getAction();
// ActionProxy proxy = invocation.getProxy();
ActionContext actionContext = invocation.getInvocationContext();
String result = null;
if (actionContext.getSession().get("username") == null
|| "".equals(actionContext.getSession().get("username"))) {
return "login";
}
result = invocation.invoke();
return result;
}
}
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>登陆界面</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">
</head>
<body>
<form action="/web/test/login.action" method="post">
UserName:<input name="username" /><br />
Password:<input name="password" type="password" /><br />
<input type="submit" name="method:login" value="登陆" />
</form>
</body>
</html>
接下来是struts配置:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.devMode" value="true" />
<constant name="struts.action.extension" value="action,,do,webwork"></constant>
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>
<package name="basicstruts2" extends="struts-default"
namespace="/test">
<interceptors>
<interceptor name="LoginInterceptor"
class="com.thr.struts2.interceptor.LoginInterceptor" />
<interceptor-stack name="myStack">
<interceptor-ref name="defaultStack" />
<interceptor-ref name="LoginInterceptor" />
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="myStack" />
<global-results>
<result name="login">/login.jsp</result>
</global-results>
<action name="user" class="com.thr.struts2.action.UserAction">
<result name="add_input">/add_input.jsp</result>
<result name="add_success">/add_success.jsp</result>
<result>/success.jsp</result>
<result name="list">/list.jsp</result>
<result name="static">/methodcalls.jsp</result>
</action>
<action name="login" class="com.thr.struts2.action.LoginAction">
<interceptor-ref name="defaultStack" />
<result>/success.jsp</result>
</action>
</package>
</struts>
这里需要讲解的比较多。
开头我们定义了一个拦截器栈,放入了defaultStack和我们定义的LoginInterceptor,接下来是一个default-interceptor-ref,这个东西的意思是,当你的action什么都没有配置拦截器的时候,就默认引入了这个拦截器,我们这里放的默认拦截器是我们自定义的myStack拦截器栈。接下来有一个global-results,这个东西是一个全局的结果集,表示无论是什么action,只要结果是"login"的时候,都会跳转到login.jsp页面。然后在user的action中没有指定拦截器,那么它默认使用的是我们自定义的myStack拦截器,下面的login的Action指定了使用的是defaultStack拦截器,就不会使用我们的myStack拦截器了,这么做的用意是什么的?当我们在登录action的时候,应该是不需要验证是否登录的,所以我们要指定好一个拦截器,才能不使用自定义的拦截器,在其他的action中都需要判断用户是否登录,所以不用配置拦截器就默认使用了我们自定义的myStack拦截器。
四. struts配置文件中的OGNL表达式
OGNL表达式还可以在struts配置文件中使用。
在程序中我们这样存入一个值:
ActionContext.getContext().put("loginjsp", "/donotlike.jsp");
然后就可以在配置文件中这样来使用:
<result name="login">%{#loginjsp}</result>
如果要是访问Action中的属性,就不用加#了,可以直接使用%{loginjsp}了。