Chinaunix首页 | 论坛 | 博客
  • 博客访问: 26321075
  • 博文数量: 2065
  • 博客积分: 10377
  • 博客等级: 上将
  • 技术积分: 21525
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-04 17:50
文章分类

全部博文(2065)

文章存档

2012年(2)

2011年(19)

2010年(1160)

2009年(969)

2008年(153)

分类: Java

2010-06-14 22:30:04

最基础的---拦截器

如果想做DEMO的话快速开发的话我们就可以使用这样的一种WEB框架。能够快速实现开发工作!要保持对技术的敏感与更新哦。要多学习新的框架技术提高开发的速度!

一、什么是拦截器

拦截器AOP中用于在某个方法或字段被访问之间,进行拦截然后在之前或之后加入某些操作进来。拦截就是AOP的一种实现策略。

拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者定义在一个action执行前后执行的代码,也可以在一个action执行前阻止其执行。

谈到拦截器,还有一个词大家应该知道——拦截器链(Interceptor Chain,在Struts 2中称为拦截器栈Interceptor Stack)。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。

(相当于定义了多个拦截器的一个组合一起进行拦截它!)

 

实现原理

当请求到达Struts 2ServletDispatcher时,Struts 2会查找配置文件,并根据其配置实例化相对的拦截器对象,然后串成一个列表(list),最后一个一个地调用列表中的拦截器,如图1所示。

即在Action之前定义一组多个拦截器。然后再丢给Action处理。处理之后将结果Result返回给客户端去。

 

目前已有的拦截器

< interceptor name ="alias" class ="com.opensymphony.xwork2.interceptor.AliasInterceptor" />
< interceptor name ="autowiring"

class ="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor" />
< interceptor name ="chain" class ="com.opensymphony.xwork2.interceptor.ChainingInterceptor" />
< interceptor name ="conversionError"

class ="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor" />
< interceptor name ="createSession" class ="org.apache.struts2.interceptor.CreateSessionInterceptor" />
< interceptor name ="debugging"

class ="org.apache.struts2.interceptor.debugging.DebuggingInterceptor" />
< interceptor name ="external-ref"

class ="com.opensymphony.xwork2.interceptor.ExternalReferencesInterceptor" />
< interceptor name ="execAndWait"

class ="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor" />
< interceptor name ="exception"

class ="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor" />
< interceptor name ="fileUpload" class ="org.apache.struts2.interceptor.FileUploadInterceptor" />
< interceptor name ="i18n" class ="com.opensymphony.xwork2.interceptor.I18nInterceptor" />
< interceptor name ="logger" class ="com.opensymphony.xwork2.interceptor.LoggingInterceptor" />
< interceptor name ="model-driven"

class ="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor" />
< interceptor name ="scoped-model-driven"

class ="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor" />
< interceptor name ="params" class ="com.opensymphony.xwork2.interceptor.ParametersInterceptor" />
< interceptor name ="prepare" class ="com.opensymphony.xwork2.interceptor.PrepareInterceptor" />
< interceptor name ="static-params"

class ="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor" />
< interceptor name ="scope" class ="org.apache.struts2.interceptor.ScopeInterceptor" />
< interceptor name ="servlet-config" class ="org.apache.struts2.interceptor.ServletConfigInterceptor" />
< interceptor name ="sessionAutowiring"

class ="org.apache.struts2.spring.interceptor.SessionContextAutowiringInterceptor" />
< interceptor name ="timer" class ="com.opensymphony.xwork2.interceptor.TimerInterceptor" />
< interceptor name ="token" class ="org.apache.struts2.interceptor.TokenInterceptor" />
< interceptor name ="token-session"

class ="org.apache.struts2.interceptor.TokenSessionStoreInterceptor" />
< interceptor name ="validation" class ="com.opensymphony.xwork2.validator.ValidationInterceptor" />
< interceptor name ="workflow"

class ="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor" />
< interceptor name ="store" class ="org.apache.struts2.interceptor.MessageStoreInterceptor" />
< interceptor name ="checkbox" class ="org.apache.struts2.interceptor.CheckboxInterceptor" />
< interceptor name ="profiling" class ="org.apache.struts2.interceptor.ProfilingActivationInterceptor" />

配置与使用拦截器

struts-default.xml中已经配置了以上的拦截器。

<package name="IOCDemo" extends="struts-default"> 哦原来继承的原因是它老人家自己定义了好多的拦截器与过滤器之类 的东西的!

如果您想要使用上述拦截器,只需要在应用程序struts.xml文件中通过struts-default.xml文件包含进来,并继承其中的struts-default包(package),最后在定义Action时,使用引用拦截器或拦截器栈(interceptor stack)。一旦您继承了struts-default包(package),所有Action都会调用拦截器栈 ——defaultStack。当然,在Action配置中加入可以覆盖defaultStack

 

1、  包含进来 包含进来

2、  包还是继承吧<package name="IOCDemo" extends="struts-default">

3、  使用了 就可以引用这个拦截器的!

 

以下示例是一个拦截器timer的使用

第一步:编写拦截器类

package tutorial;

import com.opensymphony.xwork2.ActionSupport;

public class TimerInterceptorAction extends ActionSupport {

    @Override

    public String execute() {

        try {

            //模拟耗时的操作

            Thread.sleep(500);

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

        return SUCCESS;

    }

}

第二步:配置拦截器

<struts>

    <include file="struts-default.xml"/>这个得包含进来才行的!

    <package name="InterceptorDemo" extends="struts-default">

        <action name="Timer" class="tutorial.TimerInterceptorAction">

            <interceptor-ref name="timer" />这个表示应用拦截器

            <result>/Timer.jspresult>     成功之后就跑到这个JSP页面了。

        action>

    package>

struts>

第三步:编写Timer.jsp页面

随便写点啥。

运行

可以在后台打印出来时间看到值!

上述例子演示了拦截器timer的用途——用于显示执行某个action方法的耗时,在我们做一个粗略的性能调试时,这相当有用。

 

想要检查一下某个Action的耗时情况就可以使用它进行操作了!

 

 

自定义拦截器

大家在开始着手创建自定义拦截器前,切记以下原则:
拦截器必须是无状态的,不要使用在API提供的ActionInvocation之外的任何东西。

要求拦截器是无状态的原因是Struts 2不能保证为每一个请求或者action创建一个实例,所以如果拦截器带有状态,会引发并发问题。

 

所有的Struts 2的拦截器都直接或间接实现接口com.opensymphony.xwork2.interceptor.Interceptor。除此之外,大家可能更喜欢继承类com.opensymphony.xwork2.interceptor.AbstractInterceptor

以下例子演示通过继承AbstractInterceptor,实现授权拦截器。

 

 

示例:一个封装session操作的。框架是什么:框架其实就是把我们常用的东西打包

首先,创建授权拦截器类tutorial.AuthorizationInterceptor

package tutorial;

import com.opensymphony.xwork2.Action;

import com.opensymphony.xwork2.ActionInvocation;

import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

import java.util.Map;

import javax.annotation.security.RolesAllowed;

public class AuthorizationInterceptor extends AbstractInterceptor  {

@Override

public String intercept(ActionInvocation ai) throws Exception {

Map session = (Map) 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,我定义了接口tutorial.RoleAware,代码如下:

package tutorial;

public interface RoleAware {

    void setRole(String role);

}

接着,创建Actiontutorial.AuthorizatedAccess模拟访问受限资源,它作用就是通过实现RoleAware获取角色,并将其显示到ShowUser.jsp中。

package tutorial;

 

import com.opensymphony.xwork2.ActionSupport;

 

public class AuthorizatedAccess extends ActionSupport implements RoleAware {

    private String role;

 

    public String getRole() {

        return role;

    }

 

    public void setRole(String role) {

        this.role = role;

    }

    @Override

    public String execute() {

        return SUCCESS;

    }

}

以下是ShowUser.jsp的代码:

<body>

    This is my JSP page. your role is <s:property value="role" /><br>

  body>

然后,创建tutorial.Roles初始化角色列表,代码如下:

package tutorial;
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实例化tutorial.Roles,并将其roles属性赋予标志,代码如下:

<s:bean name="tutorial.Roles" id="roles" />

    <s:form action="Login">

        <s:radio list="#roles.roles" value="EMPOLYEE" name="role" label="Role">s:radio>

        <s:submit>s:submit>

                                                          s:form>  

创建Actiontutorial.Loginrole放到session中,并转到Actiontutorial.AuthorizatedAccess

package tutorial;

 

import java.util.Map;

 

import org.apache.struts2.interceptor.SessionAware;

 

import com.opensymphony.xwork2.ActionSupport;

 

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;

}

}

最后配置文件

xml version="1.0" encoding="UTF-8"?>

DOCTYPE struts PUBLIC 

     "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" 

     ""> 

<struts>

    <include file="struts-default.xml"/>

    <package name="InterceptorDemo" extends="struts-default">

        <interceptors>

            <interceptor name ="auth" class ="tutorial.AuthorizationInterceptor" />

        interceptors >

        <action name ="Timer" class ="tutorial.TimerInterceptorAction" >

            <interceptor-ref name ="timer" />

            <result> /Timer.jsp result>

        action >

        <action name ="Login" class ="tutorial.Login" >

            <result type ="chain" > AuthorizatedAccess result >

        action >

        <action name ="AuthorizatedAccess" class ="tutorial.AuthorizatedAccess" >

            <interceptor-ref name ="auth" />

            <result name ="login" > /Login.jsp result >

            <result name ="success" > /ShowUser.jsp result >

        action >

    package>

struts>

 

拦截器是Struts 2比较重要的一个功能。通过正确地使用拦截器,我们可以编写高可复用的代码。

 

 

 

我的几点认识

1、  配置里面的

<action name ="Timer" class ="tutorial.TimerInterceptorAction" >

   <interceptor-ref name ="timer" />

   <result> /Timer.jsp result>

action >

注意里面的拦截器的名称timer必须要与Action同名的。要不然就找不到拦截器了!因为拦截器是与Action捆绑在一块的!

 

阅读(869) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~