Struts2中的拦截器

一、使用自定义拦截器,实现和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。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值