Strust2拦截器自定义拦截器实例--登录

来源:互联网 发布:windows 怎么使用ssh 编辑:程序博客网 时间:2024/05/21 22:38

 の

一、理解Struts2拦截器


1. Struts2拦截器是在访问某个Action或Action的某个方法,字段之前或之后实施拦截,并且Struts2拦截器是可动态配置的,拦截器是AOP的一种实现.


2. 拦截器栈(Interceptor Stack)。Struts2拦截器栈就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,Struts2拦截器链中的拦截器就会按其之前定义的顺序被调用。


二、实现Struts2拦截器原理(拦截器栈)


拦截器链(Interceptor Chain,在Struts 2中称为拦截器栈Interceptor Stack)。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。

当Action请求到来的时候,会由系统的代理生成一个Action的代理对象,由这个代理对象调用Action的execute()或指定的方法,并在struts.xml中查找与该Action对应的拦截器。如果有对应的拦截器,就在Action的方法执行前(后)调用这些拦截器;如果没有对应的拦截器则执行Action的方法。其中系统对于拦截器的调用,是通过ActionInvocation来实现的。


三、定义Struts2拦截器

Struts2规定用户自定义拦截器必须实现com.opensymphony.xwork2.interceptor.Interceptor接口。

其中,init和destroy方法会在程序开始和结束时各执行一遍,不管使用了该拦截器与否,只要在struts.xml中声明了该Struts2拦截器就会被执行。
intercept方法就是拦截的主体了,每次拦截器生效时都会执行其中的逻辑。


不过,struts中又提供了几个抽象类来简化:

public abstract class AbstractInterceptor implements Interceptor;
public abstract class LoginInterceptor extends AbstractInterceptor


这些都是模板方法实现的。


其中AbstractInterceptor提供了init()和destroy()的空实现,使用时只需要覆盖intercept()方法;


而MethodFilterInterceptor则提供了includeMethods和excludeMethods两个属性,用来过滤执行该过滤器的action的方法。可以通过param来加入或者排除需要过滤的方法。



Action代码如下:

package com.redhamr.web.member.interceptor;import java.util.Map;import com.opensymphony.xwork2.Action;import com.opensymphony.xwork2.ActionContext;import com.opensymphony.xwork2.ActionInvocation;import com.opensymphony.xwork2.interceptor.AbstractInterceptor;import com.redhamr.persistent.model.Member;import com.redhamr.web.member.GlobalConstantWeb;public class LoginInterceptor extends AbstractInterceptor {/** *  */private static final long serialVersionUID = 1L;@Overridepublic String intercept(ActionInvocation invocation) throws Exception {// TODO Auto-generated method stub// 取得请求相关的ActionContext实例ActionContext ctx = invocation.getInvocationContext();Map session = ctx.getSession();Member user = (Member) session.get(GlobalConstantWeb.SESSION_MEMBER);// 如果没有登陆,返回重新登陆if (user != null) {return invocation.invoke();}ctx.put("tip", "你还没有登录");return "login";}}


strust2.xml

<package name="member" extends="json-default"><interceptors><interceptor name="authority"class="com.redhamr.web.member.interceptor.LoginInterceptor"></interceptor><!-- 拦截器栈 --><interceptor-stack name="mydefault"><interceptor-ref name="authority" /><interceptor-ref name="defaultStack" /></interceptor-stack></interceptors><default-interceptor-ref name="mydefault" /><global-results><result name="login" type="redirect">/Website_index_login.rhm</result></global-results><action name="Website_user_*"><result>/WEB-INF/user/{1}.jsp</result></action></package>

在interceptor-ref中也可以通过param标签来设置一些特殊要求,param的name属性不同效果也不同,例子如下


更改拦截器的name属性


<param name="name">更改拦截器以后的名字</param>


 


不需要拦截的方法名


<param name="aa">不需拦截的方法名以逗号隔开</param>


需要拦截的方法名


<param name="bb">需拦截的方法名以逗号隔开</param>


注:当aa和bb属性都存在时,则bb属性优先级更高。


 

 
JSP展示页面:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@ taglib prefix="s" uri="/struts-tags"%><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><TITLE><sitemesh:write property='title' /></TITLE><sitemesh:write property='head' /><script type="text/javascript" src="scripts/jquery.js"></script><script type="text/javascript" src="scripts/run.js"></script><script type="text/javascript" src="scripts/page.js"></script><script type="text/javascript" src="scripts/jquery-ui.js"></script><script type="text/javascript" src="scripts/jquery.zoomImgRollover.js"></script><link type="text/css" rel="stylesheet" href="style/first.css" /><link type="text/css" rel="stylesheet" href="style/main.css" /><link type="text/css" rel="stylesheet" href="style/footer.css" /><link type="text/css" rel="stylesheet" href="style/header.css" /><link type="text/css" rel="stylesheet" href="style/perCenter.css" /><link type="text/css" rel="stylesheet" href="style/jquery-ui.css" /><script>$(document).ready(function() {$(".testimg").zoomImgRollover();});$(function() {$("input.datepicker").datepicker();});</script></head><!--导航栏和头部开始--><div class="head"><div class="head1"><ul class="ul_li_f_left h_margin"><li>欢迎致电 :</li><li class="FontSize17px">400-691-7677</li><li>服务时间:</li><li>9:00 - 19:00</li><li class="h_hei_dad"><div class="h_hei_wid1"></div></li><li class="h_hei_dad"><div class="h_hei_wid2"></div></li></ul><ul class="ul_li_f_left h_margin2"><li class="firstWord"><a href="#">网站活动</a></li><!-- <li><a href="#">下载客户端</a></li> --><s:if test="null==#session.MEMBER||#session.MEMBER.isEmpty()"><li><a href="toLogin.rhm">登录</a></li></s:if><s:else><li>${session.MEMBER.username}  <s:a action="merchloginout">注销</s:a></li></s:else><li class="lastWord"><a href="toRegister.rhm">快捷注册</a></li></ul></div></div><div class="PageDad"> <div class="Page">   <ul class="ul_li_f_left P_nav">   <li class="P_logo"><a href="Website_index.rhm"></a></li>   <li><a href="proLists.rhm?pageSize=8">我要投资</a></li>   <li><a href="#">新手专区</a></li>   <li><a href="#">安全保障</a></li>   <li><a href="#">平安论坛</a></li>   <li><a href="memCenter.rhm">我的账户</a></li>   </ul>  </div></div><sitemesh:write property='body'></sitemesh:write>


 

拦截器的执行流程:


拦截器的执行顺序和在struts.xml的配置顺序是有关,也就是说如果a拦截器在b拦截器之前被声明,则会先进入a拦截器,然后进入b拦截器。值得注意的是b拦截器执行之后会回到a拦截器继续执行之后的内容。


特别注意,在使用拦截器的时候,在Action里面必须最后一定要引用struts2自带的拦截器缺省堆栈defaultStack.


0 0