一、使用自定义拦截器,实现和timer效果一样的拦截器。
timer源码:
public class TimerInterceptor extends AbstractInterceptor {
private static final Logger LOG = LogManager.getLogger(TimerInterceptor.class);
protected Logger categoryLogger;
protected String logCategory;
protected String logLevel;
public String getLogCategory() {
return logCategory;
}
public void setLogCategory(String logCatgory) {
this.logCategory = logCatgory;
}
public String getLogLevel() {
return logLevel;
}
public void setLogLevel(String logLevel) {
this.logLevel = logLevel;
}
@Override
public String intercept(ActionInvocation invocation) throws Exception {
if (! shouldLog()) {
return invocation.invoke();
} else {
return invokeUnderTiming(invocation);
}
}
/**
* Is called to invoke the action invocation and time the execution time.
*
* @param invocation the action invocation.
* @return the result of the action execution.
* @throws Exception can be thrown from the action.
*/
protected String invokeUnderTiming(ActionInvocation invocation) throws Exception {
long startTime = System.currentTimeMillis();
String result = invocation.invoke();
long executionTime = System.currentTimeMillis() - startTime;
StringBuilder message = new StringBuilder(100);
message.append("Executed action [");
String namespace = invocation.getProxy().getNamespace();
if (StringUtils.isNotBlank(namespace)) {
message.append(namespace).append("/");
}
message.append(invocation.getProxy().getActionName());
message.append("!");
message.append(invocation.getProxy().getMethod());
message.append("] took ").append(executionTime).append(" ms.");
doLog(getLoggerToUse(), message.toString());
return result;
}
/**
* Determines if we should log the time.
*
* @return true to log, false to not log.
*/
protected boolean shouldLog() {
// default check first
if (logLevel == null && logCategory == null) {
return LOG.isInfoEnabled();
}
// okay user have set some parameters
return isLoggerEnabled(getLoggerToUse(), logLevel);
}
/**
* Get's the logger to use.
*
* @return the logger to use.
*/
protected Logger getLoggerToUse() {
if (logCategory != null) {
if (categoryLogger == null) {
// init category logger
categoryLogger = LogManager.getLogger(logCategory);
if (logLevel == null) {
logLevel = "info"; // use info as default if not provided
}
}
return categoryLogger;
}
return LOG;
}
/**
* Performs the actual logging.
*
* @param logger the provided logger to use.
* @param message the message to log.
*/
protected void doLog(Logger logger, String message) {
if (logLevel == null) {
logger.info(message);
return;
}
if ("debug".equalsIgnoreCase(logLevel)) {
logger.debug(message);
} else if ("info".equalsIgnoreCase(logLevel)) {
logger.info(message);
} else if ("warn".equalsIgnoreCase(logLevel)) {
logger.warn(message);
} else if ("error".equalsIgnoreCase(logLevel)) {
logger.error(message);
} else if ("fatal".equalsIgnoreCase(logLevel)) {
logger.fatal(message);
} else if ("trace".equalsIgnoreCase(logLevel)) {
logger.trace(message);
} else {
throw new IllegalArgumentException("LogLevel [" + logLevel + "] is not supported");
}
}
/**
* Is the given logger enalbed at the given level?
*
* @param logger the logger.
* @param level the level to check if <code>isXXXEnabled</code>.
* @return <tt>true</tt> if enabled, <tt>false</tt> if not.
*/
private static boolean isLoggerEnabled(Logger logger, String level) {
if ("debug".equalsIgnoreCase(level)) {
return logger.isDebugEnabled();
} else if ("info".equalsIgnoreCase(level)) {
return logger.isInfoEnabled();
} else if ("warn".equalsIgnoreCase(level)) {
return logger.isWarnEnabled();
} else if ("error".equalsIgnoreCase(level)) {
return logger.isErrorEnabled();
} else if ("fatal".equalsIgnoreCase(level)) {
return logger.isFatalEnabled();
} else if ("trace".equalsIgnoreCase(level)) {
return logger.isTraceEnabled();
} else {
throw new IllegalArgumentException("LogLevel [" + level + "] is not supported");
}
}
}
Action类
import com.opensymphony.xwork2.ActionSupport;
public class LoginAction extends ActionSupport{
private String username;
private String password;
// username的setter和getter方法
public void setUsername(String username){
this.username = username;
}
public String getUsername(){
return username;
}
// password的setter和getter方法
public void setPassword(String password){
this.password = password;
}
public String getPassword(){
return password;
}
public String execute() throws Exception{
System.out.println("进入execute方法执行体..........");
if (getUsername().equals("张三")&& getPassword().equals("123456") ){
return SUCCESS;
}
return ERROR;
}
}
自定义拦截器:
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import java.util.*;
import org.crazyit.app.action.*;
public class SimpleInterceptor extends AbstractInterceptor{
// 简单拦截器的名字
private String name;
// 为该简单拦截器设置名字的setter方法
public void setName(String name){
this.name = name;
}
public String intercept(ActionInvocation invocation)throws Exception{
// 取得被拦截的Action实例
LoginAction action = (LoginAction)invocation.getAction();
// 打印执行开始的时间
System.out.println(name + " 拦截器的动作---------" +"开始执行登录Action的时间为:" + new Date());
// 取得开始执行Action的时间
long start = System.currentTimeMillis();
// 执行该拦截器的后一个拦截器
// 如果该拦截器后没有其他拦截器,则直接执行Action的被拦截方法
String result = invocation.invoke();
// 打印执行结束的时间
System.out.println(name + " 拦截器的动作---------" +"执行完登录Action的时间为:" + new Date());
long end = System.currentTimeMillis();
System.out.println(name + " 拦截器的动作---------" +"执行完该Action的时间为" + (end - start) + "毫秒");
return result;
}
}
自定义拦截器需要继承AbstractInterceptor类,这个拦截器会拦截该Action内的所有方法。
struts.xml
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<constant name="struts.i18n.encoding" value="gbk"></constant>
<!-- 配置国际化资源文件 -->
<constant name="struts.custom.i18n.resources" value="GBK" />
<!-- 通过常量配置该应用所使用的字符集 -->
<constant name="struts.i18n.encoding" value="GBK" />
<!-- 配置本系统所使用的包 -->
<package name="lee" extends="struts-default">
<!-- 应用所需使用的拦截器都在该元素下配置 -->
<interceptors>
<!-- 配置mySimple拦截器 -->
<interceptor name="mySimple"
class="org.crazyit.app.interceptor.SimpleInterceptor">
<!-- 为拦截器指定参数值 -->
<param name="name">简单拦截器</param>
</interceptor>
</interceptors>
<action name="login" class="org.crazyit.app.action.LoginAction">
<result name="error">/WEB-INF/content/error.jsp</result>
<result>/WEB-INF/content/welcome.jsp</result>
<!-- 配置系统的默认拦截器 -->
<interceptor-ref name="defaultStack" />
<!-- 应用自定义的mySimple拦截器 -->
<interceptor-ref name="mySimple">
<param name="name">改名后的拦截器</param><!-- 这里会覆盖前面默认的默认值 -->
</interceptor-ref>
</action>
<action name="*">
<result>/WEB-INF/content/{1}.jsp</result>
</action>
</package>
</struts>
loginForm.jsp
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>登录页面</title>
</head>
<body>
<h3>用户登录</h3>
<s:form action="login">
<s:textfield name="username" label="用户名"/>
<s:password name="password" label="密码"/>
<s:submit value="登录"/>
</s:form>
</body>
</html>
二、拦截指定的方法。
继承关系:
MethodFilterInterceptor--> AbstractInterceptor--> Interceptor--> Serializable
前面实现的方法是intercept,而后面实现的方法是doIntercept
Action类
import com.opensymphony.xwork2.ActionSupport;
public class LoginAction extends ActionSupport{
private String username;
private String password;
// username的setter和getter方法
public void setUsername(String username){
this.username = username;
}
public String getUsername(){
return username;
}
// password的setter和getter方法
public void setPassword(String password){
this.password = password;
}
public String getPassword(){
return password;
}
public String execute() throws Exception{
System.out.println("进入execute方法执行体..........");
if (getUsername().equals("张三")&& getPassword().equals("123456") ){
return SUCCESS;
}
return ERROR;
}
}
之定义拦截器:
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.*;
import java.util.*;
import org.crazyit.app.action.*;
// 拦截方法的拦截器,应该继承MethodFilterInterceptor抽象类
public class MyFilterInterceptor extends MethodFilterInterceptor{
// 拦截器的名字
private String name;
// 为该拦截器设置名字的setter方法
public void setName(String name){
this.name = name;
}
// 重写doIntercept()方法,实现对Action的拦截逻辑
public String doIntercept(ActionInvocation invocation)throws Exception{
System.out.println("MyFilterInterceptor.doIntercept()");
// 取得被拦截的Action实例
LoginAction action = (LoginAction)invocation.getAction();
// 打印执行开始的时间
System.out.println(name + " 拦截器的动作---------"+ "开始执行登录Action的时间为:" + new Date());
// 取得开始执行Action的时间
long start = System.currentTimeMillis();
// 执行该拦截器的后一个拦截器,或者直接指定Action的被拦截方法
String result = invocation.invoke();
// 打印执行结束的时间
System.out.println(name + " 拦截器的动作---------"+ "执行完登录Action的时间为:" + new Date());
long end = System.currentTimeMillis();
// 打印执行该Action所花费的时间
System.out.println(name + " 拦截器的动作---------"+ "执行完该Action的时间为" + (end - start) + "毫秒");
return result;
}
}
自定义拦截器需要继承AbstractInterceptor类,这个拦截器会拦截该Action内的所有方法。
struts.xml
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<!-- 通过常量配置该应用所使用的字符集 -->
<constant name="struts.i18n.encoding" value="GBK" />
<!-- 配置本系统所使用的包 -->
<package name="lee" extends="struts-default">
<!-- 应用所需使用的拦截器都在该元素下配置 -->
<interceptors>
<!-- 配置mySimple拦截器 -->
<interceptor name="mySimple"
class="org.crazyit.app.interceptor.MyFilterInterceptor">
<!-- 为拦截器指定参数值 -->
<param name="name">拦截方法的拦截器</param>
</interceptor>
</interceptors>
<action name="login" class="org.crazyit.app.action.LoginAction">
<result name="error">/WEB-INF/content/error.jsp</result>
<result>/WEB-INF/content/welcome.jsp</result>
<!-- 配置系统的默认拦截器 -->
<interceptor-ref name="defaultStack" />
<!-- 应用自定义的mySimple拦截器 -->
<interceptor-ref name="mySimple">
<!-- 重新指定name属性的属性值 -->
<param name="name">改名后的拦截方法过滤拦截器</param>
<!-- 指定execute方法不需要被拦截 不会执行doIntercept方法 -->
<param name="excludeMethods">execute</param>
<!-- <param name="includeMethods">execute</param> -->
</interceptor-ref>
</action>
<action name="*">
<result>/WEB-INF/content/{1}.jsp</result>
</action>
</package>
</struts>
<!-- 指定execute方法不需要被拦截 不会执行doIntercept方法 -->
<param name="excludeMethods">execute</param>
<!-- 指定execute方法需要被拦截 会执行doIntercept方法 -->
<param name="includeMethods">execute</param>
同时指定的话会执行。
loginForm.jsp
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>登录页面</title>
</head>
<body>
<h3>用户登录</h3>
<s:form action="login">
<s:textfield name="username" label="用户名"/>
<s:password name="password" label="密码"/>
<s:submit value="登录"/>
</s:form>
</body>
</html>
三、使用拦截器完成权限控制。
struts.xml
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<constant name="struts.i18n.encoding" value="GBK" />
<package name="lee" extends="struts-default">
<!-- 用户拦截器定义在该元素下 -->
<interceptors>
<!-- 定义了一个名为authority的拦截器 -->
<interceptor name="authority"
class="org.crazyit.app.interceptor.AuthorityInterceptor" />
<interceptor-stack name="myStack">
<interceptor-ref name="authority"></interceptor-ref>
<interceptor-ref name="defaultStack" />
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="myStack" /><!--
定义一个默认的拦截器栈,所有的方法只要不显示的指定拦截器,都将使用这个默认的拦截器栈 -->
<!-- 定义全局Result -->
<global-results>
<!-- 当返回login视图名时,转入loginForm.jsp页面 -->
<result name="login">/WEB-INF/content/loginForm.jsp</result>
</global-results>
<!-- 定义一个名为 的Action,其实现类为ActionSupport -->
<action name="viewBook">
<!-- 返回success视图名时,转入viewBook.jsp页面 -->
<result>/WEB-INF/content/viewShow.jsp</result>
</action>
<action name="*">
<result>/WEB-INF/content/{1}.jsp</result>
</action>
</package>
<package name="default" extends="struts-default">
<!-- 这个包下的方面没有默认的拦截器栈 -->
<action name="login" class="org.crazyit.app.action.LoginAction">
<result name="error">/WEB-INF/content//error.jsp</result>
<result>/WEB-INF/content/welcome.jsp</result>
</action>
</package>
</struts>
注意拦截器的放置顺序<default-interceptor-ref />放在了<interceptors>最后。
Action类
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ActionContext;
import java.util.*;
public class LoginAction extends ActionSupport
{
private String username;
private String password;
// username的setter和getter方法
public void setUsername(String username)
{
this.username = username;
}
public String getUsername()
{
return this.username;
}
// password的setter和getter方法
public void setPassword(String password)
{
this.password = password;
}
public String getPassword()
{
return this.password;
}
public String execute() throws Exception
{
System.out.println("进入execute方法执行体..........");
if (getUsername().equals("张三")
&& getPassword().equals("123456") )
{
ActionContext ctx = ActionContext.getContext();
Map<String,Object> session = ctx.getSession();
session.put("user" , getUsername());
return SUCCESS;
}
return ERROR;
}
}
自定义拦截器
import com.opensymphony.xwork2.*;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import java.util.*;
// 权限检查拦截器继承AbstractInterceptor类
public class AuthorityInterceptor
extends AbstractInterceptor
{
// 拦截Action处理的拦截方法
public String intercept(ActionInvocation invocation)
throws Exception
{
System.out.println("AuthorityInterceptor.intercept()");
// 取得请求相关的ActionContext实例
ActionContext ctx = invocation.getInvocationContext();
Map session = ctx.getSession();
// 取出Session里的user属性
String user = (String)session.get("user");
//如果没有登录,或者登录所用的用户名不是张三,都返回重新登录
if (user != null && user.equals("张三") )
{
return invocation.invoke();
}
// 如果没有登录,将服务器提示放入ActionContext中
ctx.put("tip" ,"您还没有登录,请输入张三,123456登录系统");
// 返回login的逻辑视图
return Action.LOGIN;
}
}
loginForm.jsp
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>登录页面</title>
</head>
<body>
<h3>用户登录</h3>
${tip}
<s:form action="login">
<s:textfield name="username" label="用户名"/>
<s:password name="password" label="密码"/>
<s:submit value="登录"/>
</s:form>
</body>
</html>
welcome.jsp
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>成功页面</title>
</head>
<body>
您已经登录!
<a href="viewBook">查看详细信息</a>
</body>
</html>
viewShow.jsp
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>欢迎李张三:</title>
<meta name="website" content="http://www.crazyit.org"/>
</head>
<body>
<h2>欢迎李张三:</h2>
欢迎李张三<br/>
欢迎李张三<br/>
欢迎李张三<br/>
</body>
</html>
error.jsp
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>错误页面</title>
</head>
<body>
您不能登录!
</body>
</html>
d
没有登录的时候去访问其他页面会调回到登录页面loginForm.jsp。