Struts2拦截器

如何使用struts2拦截器,或者自定义拦截器。特别注意,在使用拦截器的时候,在Action里面必须最后一定要引用struts2自带的拦截器缺省堆栈defaultStack,如下(这里我是引用了struts2自带的checkbox拦截器):
<interceptor-ref name="checkbox">
  <param name="uncheckedValue">0</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"/>(必须加,否则出错)
也可以改为对全局Action设置自己需要的拦截器,如下:

在struts.xml里面定义全局的配置设置
  <package name="struts-shop" extends="struts-default">
    <interceptors>
      <interceptor-stack name="myStack">
        <interceptor-ref name="checkbox">
          <param name="uncheckedValue">0</param>
       </interceptor-ref>
       <interceptor-ref name="defaultStack"/>
      </interceptor-stack>
    </interceptors>
    <default-interceptor-ref name="myStack"/>(这句是设置所有Action自动调用的拦截器堆栈)
  </package>
 
struts-action.xml里面配置Action如下:
  <package name="LogonAdmin" extends="struts-shop">(这里扩展struts.xml里面定义的配置就可以了)
  <action name="logon" class="logonAction">
     <result>/jsp/smeishop/admin/index.jsp</result>
     <result name="error">/jsp/smeishop/admin/logon.jsp</result>
     <result name="input">/jsp/smeishop/admin/logon.jsp</result>
   </action>
   <action name="logout" class="logoutAction">
     <result>/jsp/smeishop/admin/logon.jsp</result>
   </action>
 </package>

你的拦截器可以正常工作了!!HOHO
以下是参考资料
struts2自带的配置及其拦截器配置

复制代码

Struts2 拦截器 [Interceptor]

拦截器的工作原理如上图,每一个Action请求都包装在一系列的拦截器的内部。拦截器可以在Action执行直线做相似的操作也可以在Action执行直后做回收操作。

 

每一个Action既可以将操作转交给下面的拦截器,Action也可以直接退出操作返回客户既定的画面。

 

如何自定义一个拦截器?

自定义一个拦截器需要三步:

1 自定义一个实现Interceptor接口(或者继承自AbstractInterceptor)的类。

2 在strutx.xml中注册上一步中定义的拦截器。

3 在需要使用的Action中引用上述定义的拦截器,为了方便也可将拦截器定义为默认的拦截器,这样在不加特殊声明的情况下所有的Action都被这个拦截器拦截。

 

Interceptor接口声明了三个方法:

复制代码

public interface Interceptor extends Serializable {
 
    void destroy();
 
    void init();
 
    String intercept(ActionInvocation invocation) throws Exception;
}

复制代码

Init方法在拦截器类被创建之后,在对Action镜像拦截之前调用,相当于一个post-constructor方法,使用这个方法可以给拦截器类做必要的初始话操作。 

Destroy方法在拦截器被垃圾回收之前调用,用来回收init方法初始化的资源。 

Intercept是拦截器的主要拦截方法,如果需要调用后续的Action或者拦截器,只需要在该方法中调用invocation.invoke()方法即可,在该方法调用的前后可以插入Action调用前后拦截器需要做的方法。如果不需要调用后续的方法,则返回一个String类型的对象即可,例如Action.SUCCESS。

另外AbstractInterceptor提供了一个简单的Interceptor的实现,这个实现为

复制代码

public abstract class AbstractInterceptor implements Interceptor {
 
     public void init() {
    }
   
    public void destroy() {
    }
 
 
    public abstract String intercept(ActionInvocation invocation) throws Exception;
}

复制代码

在不需要编写init和destroy方法的时候,只需要从AbstractInterceptor继承而来,实现intercept方法即可。

 

我们尝试编写一个Session过滤用的拦截器,该拦截器查看用户Session中是否存在特定的属性(LOGIN属性)如果不存在,中止后续操作定位到LOGIN,否则执行原定操作,代码为:

复制代码

public class CheckLoginInterceptor extends AbstractInterceptor {
    public static final String LOGIN_KEY = "LOGIN";
    public static final String LOGIN_PAGE = "global.login";
 
    public String intercept(ActionInvocation actionInvocation) throws Exception {
 
        System.out.println("begin check login interceptor!");
        // 对LoginAction不做该项拦截
        Object action = actionInvocation.getAction();
        if (action instanceof LoginAction) {
            System.out.println("exit check login, because this is login action.");
            return actionInvocation.invoke();
        }
 
        // 确认Session中是否存在LOGIN
        Map session = actionInvocation.getInvocationContext().getSession();
        String login = (String) session.get(LOGIN_KEY);
        if (login != null && login.length() > 0) {
            // 存在的情况下进行后续操作。
            System.out.println("already login!");
            return actionInvocation.invoke();
        } else {
            // 否则终止后续操作,返回LOGIN
            System.out.println("no login, forward login page!");
            return LOGIN_PAGE;
        }
    }
}
 
注册拦截器
<interceptors>
            <interceptor
name="login" 
class="com.jpleasure.teamware.util.CheckLoginInterceptor"/>
            <interceptor-stack name="teamwareStack">
                <interceptor-ref name="login"/>
                <interceptor-ref name="defaultStack"/>
            </interceptor-stack>
</interceptors>
 
将上述拦截器设定为默认拦截器:
<default-interceptor-ref name="teamwareStack"/>
这样在后续同一个package内部的所有Action执行之前都会被login拦截。

复制代码

Struts2(XWork)提供的拦截器的功能说明:

拦截器

名字

说明

Alias Interceptor

alias

在不同请求之间将请求参数在不同名字件转换,请求内容不变

Chaining Interceptor

chain

让前一个Action的属性可以被后一个Action访问,现在和chain类型的result(<result type=”chain”>)结合使用。

Checkbox Interceptor

checkbox

添加了checkbox自动处理代码,将没有选中的checkbox的内容设定为false,而html默认情况下不提交没有选中的checkbox。

Cookies Interceptor

cookies

使用配置的name,value来是指cookies

Conversion Error Interceptor

conversionError

将错误从ActionContext中添加到Action的属性字段中。

Create Session Interceptor

createSession

自动的创建HttpSession,用来为需要使用到HttpSession的拦截器服务。

Debugging Interceptor

debugging

提供不同的调试用的页面来展现内部的数据状况。

Execute and Wait Interceptor

execAndWait

在后台执行Action,同时将用户带到一个中间的等待页面。

Exception Interceptor

exception

将异常定位到一个画面

File Upload Interceptor

fileUpload

提供文件上传功能

I18n Interceptor

i18n

记录用户选择的locale

Logger Interceptor

logger

输出Action的名字

Message Store Interceptor

store

存储或者访问实现ValidationAware接口的Action类出现的消息,错误,字段错误等。

Model Driven Interceptor

model-driven

如果一个类实现了ModelDriven,将getModel得到的结果放在Value Stack中。

Scoped Model Driven

scoped-model-driven

如果一个Action实现了ScopedModelDriven,则这个拦截器会从相应的Scope中取出model调用Action的setModel方法将其放入Action内部。

Parameters Interceptor

params

将请求中的参数设置到Action中去。

Prepare Interceptor

prepare

如果Acton实现了Preparable,则该拦截器调用Action类的prepare方法。

Scope Interceptor

scope

将Action状态存入session和application的简单方法。

Servlet Config Interceptor

servletConfig

提供访问HttpServletRequest和HttpServletResponse的方法,以Map的方式访问。

Static Parameters Interceptor

staticParams

从struts.xml文件中将<action>中的<param>中的内容设置到对应的Action中。

Roles Interceptor

roles

确定用户是否具有JAAS指定的Role,否则不予执行。

Timer Interceptor

timer

输出Action执行的时间

Token Interceptor

token

通过Token来避免双击

Token Session Interceptor

tokenSession

和Token Interceptor一样,不过双击的时候把请求的数据存储在Session中

Validation Interceptor

validation

使用action-validation.xml文件中定义的内容校验提交的数据。

Workflow Interceptor

workflow

调用Action的validate方法,一旦有错误返回,重新定位到INPUT画面

Parameter Filter Interceptor

N/A

从参数列表中删除不必要的参数

Profiling Interceptor

profiling

通过参数激活profile

复制代码

注册并引用Interceptor
<package name="default" extends="struts-default">
   <interceptors>
       <interceptor name="timer" class=".."/>
       <interceptor name="logger" class=".."/>
   </interceptors>
 
   <action name="login" class="tutorial.Login">
        <interceptor-ref name="timer"/>
        <interceptor-ref name="logger"/>
        <result name="input">login.jsp</result>
        <result name="success"
            type="redirect-action">/secure/home</result>
   </action>
</package>
 
可以将多个拦截器合并在一起作为一个堆栈调用,当一个拦截器堆栈被附加到一个Action的时候,要想Action执行,必须执行拦截器堆栈中的每一个拦截器。
<package name="default" extends="struts-default">
   <interceptors>
        <interceptor name="timer" class=".."/>
        <interceptor name="logger" class=".."/>
        <interceptor-stack name="myStack">
           <interceptor-ref name="timer"/>
           <interceptor-ref name="logger"/>
        </interceptor-stack>
    </interceptors>
 
    <action name="login" class="tutuorial.Login">
         <interceptor-ref name="myStack"/>
         <result name="input">login.jsp</result>
         <result name="success"
             type="redirect-action">/secure/home</result>
    </action>
</package>
 
上述说明的拦截器在默认的Struts2应用中,根据惯例配置了若干个拦截器堆栈,详细情参看struts-default.xml
其中有一个拦截器堆栈比较特殊,他会应用在默认的每一个Action上。
<interceptor-stack name="defaultStack">
    <interceptor-ref name="exception"/>
    <interceptor-ref name="alias"/>
    <interceptor-ref name="servletConfig"/>
    <interceptor-ref name="prepare"/>
    <interceptor-ref name="i18n"/>
    <interceptor-ref name="chain"/>
    <interceptor-ref name="debugging"/>
    <interceptor-ref name="profiling"/>
    <interceptor-ref name="scopedModelDriven"/>
    <interceptor-ref name="modelDriven"/>
    <interceptor-ref name="fileUpload"/>
    <interceptor-ref name="checkbox"/>
    <interceptor-ref name="staticParams"/>
    <interceptor-ref name="params">
      <param name="excludeParams">dojo"..*</param>
    </interceptor-ref>
    <interceptor-ref name="conversionError"/>
    <interceptor-ref name="validation">
        <param name="excludeMethods">input,back,cancel,browse</param>
    </interceptor-ref>
    <interceptor-ref name="workflow">
        <param name="excludeMethods">input,back,cancel,browse</param>
    </interceptor-ref>
</interceptor-stack>
 
每一个拦截器都可以配置参数,有两种方式配置参数,一是针对每一个拦截器定义参数,二是针对一个拦截器堆栈统一定义所有的参数,例如:
<interceptor-ref name="validation">
 <param name="excludeMethods">myValidationExcudeMethod</param>
</interceptor-ref>
<interceptor-ref name="workflow">
 <param name="excludeMethods">myWorkflowExcludeMethod</param>
</interceptor-ref>
或者
<interceptor-ref name="defaultStack">
    <param name="validation.excludeMethods">myValidationExcludeMethod</param>
    <param name="workflow.excludeMethods">myWorkflowExcludeMethod</param>
</interceptor-ref>
 
每一个拦截器都有两个默认的参数:
excludeMethods - 过滤掉不使用拦截器的方法和
includeMethods – 使用拦截器的方法。
 
需要说明的几点:
1 拦截器执行的顺序按照定义的顺序执行,例如:
<interceptor-stack name="xaStack">
 <interceptor-ref name="thisWillRunFirstInterceptor"/>
 <interceptor-ref name="thisWillRunNextInterceptor"/>
 <interceptor-ref name="followedByThisInterceptor"/>
 <interceptor-ref name="thisWillRunLastInterceptor"/>
</interceptor-stack>
的执行顺序为:
thisWillRunFirstInterceptor
 thisWillRunNextInterceptor
    followedByThisInterceptor
      thisWillRunLastInterceptor
        MyAction1
        MyAction2 (chain)
        MyPreResultListener
        MyResult (result)
      thisWillRunLastInterceptor
    followedByThisInterceptor
 thisWillRunNextInterceptor
thisWillRunFirstInterceptor
 
2 使用默认拦截器配置每个Action都需要的拦截器堆栈,例如:
<action name="login" class="tutorial.Login">
     <interceptor-ref name="timer"/>
     <interceptor-ref name="logger"/>
     <interceptor-ref name="default-stack"/>
 
     <result name="input">login.jsp</result>
     <result type="redirect-action">/secure/home</result>
</action>
可以按照如下的方式定义:
<interceptors>
     <interceptor-stack name="myStack">
        <interceptor-ref name="timer"/>
        <interceptor-ref name="logger"/>
        <interceptor-ref name="default-stack"/>
     </interceptor-stack>
</interceptors>
 
<default-interceptor-ref name="myStack"/>
 
<action name="login" class="tutorial.Login">
       <result name="input">login.jsp</result>
       <result type="redirect-action">/secure/home</result>
</action>
 
3 如何访问HttpServletRequest,HttpServletResponse或者HttpSession
有两种方法可以达到效果,使用ActionContext:
Map attibutes = ActionContext.getContext().getSession();
或者实现相应的接口:
HttpSession            SessionAware
HttpServletRequest     ServletRequestAware
HttpServletResponse    ServletResponseAware


Struts2自定义拦截器实例—只允许从登录页面进入系统
【1】struts.xml:
 <!-- 定义一个拦截器 -->  
        <interceptors>  
            <interceptor name="authority"  
                class="org.interceptot.LoginInterceptor">  
            </interceptor>  
            
            <!-- 拦截器栈 -->  
            <interceptor-stack name="mydefault">  
                <interceptor-ref name="defaultStack" />  
                <interceptor-ref name="authority" />  
            </interceptor-stack>  
        </interceptors>
        
         
        
         <!-- 定义全局Result -->  
        <global-results>  
            <!-- 当返回login视图名时,转入/login.jsp页面 -->  
            <result name="login">/login.jsp</result>  
        </global-results>
        
        
        <action name="show" class="org.action.showAction">  
            <result name="success">/main.jsp</result>  
            <!-- 使用此拦截器 -->  
            <interceptor-ref name="mydefault" />  
        </action>  
        
        
        <!--验证登录用户信息  -->
        <action name="login" class="org.action.loginAction" method="execute">
            <result name="error">/login.jsp</result>  
            <result name="input">/login.jsp</result> 
        </action>
       
【2】自定义拦截器org.interceptot.LoginInterceptor:
package org.interceptot;
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;  
public class LoginInterceptor extends AbstractInterceptor {  
 
    @Override  
    public String intercept(ActionInvocation invocation) throws Exception {  
  
        // 取得请求相关的ActionContext实例  
        ActionContext ctx = invocation.getInvocationContext();  
        Map session = ctx.getSession();  
        String user = (String) session.get("username");  
  
        // 如果没有登陆,即用户名不存在,都返回重新登陆  
        System.out.println("user:"+user);
        if (user != null) {  
            System.out.println("test");  
            return invocation.invoke();  
        }  
        System.out.println("你还没有登录"); 
        ctx.put("tip", "你还没有登录");  
        return Action.LOGIN;    //返回一个叫login的result结果
  
    }  
  
}  
【3】进入主页面的Action:org.action.showAction
package org.action;

import com.opensymphony.xwork2.ActionSupport;  

public class showAction extends ActionSupport {  
 public String execute() {  
  return "success";  
 }  
}  

【4】LoginAction:

private boolean isInvalid(String value) {     
return (value == null || value.length() == 0);     
}  
if (isInvalid(user.getUsername()))   
       return INPUT;     
 if (isInvalid(user.getPassword()))     
       return INPUT;    
 //登录成功将User放入session中
HttpServletRequest request = ServletActionContext.getRequest();
Map  map=ActionContext.getContext().getSession();
map.put("username", user.getUsername());

【5】如果我们通过show.action访问main.jsp那么就会被自定义拦截器拦住,拦截器检查session中
是否有值,有证明用户已经登录,没有则为没有登录,那么就会被跳转到登陆页面。

 

PS:最后还附加一点过滤器的东西

 

过滤器,是在java web中,你传入的request,response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的 action进行业务逻辑,比如过滤掉非法url(不是login.do的地址请求,如果用户没有登陆都过滤掉),或者在传入servlet或者 struts的action前统一设置字符集,或者去除掉一些非法字符

拦截器,是在面向切面编程的就是在你的service或者一个方法,前调用一个方法,或者在方法后调用一个方法比如动态代理就是拦截器的简单实现,在你调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在你调用方法后打印出字符串,甚至在你抛出异常的时候做业务逻辑的操作。

拦截器与过滤器的区别 :

1、拦截器是基于java的反射机制的,而过滤器是基于函数回调。

 

2、拦截器不依赖与servlet容器,过滤器依赖与servlet容器。

3、拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。

4、拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。

5、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次

6、执行顺序 :过滤前 - 拦截前 - Action处理 - 拦截后 - 过滤后。

 

过滤是一个横向的过程,首先把客户端提交的内容进行过滤(例如未登录用户不能访问内部页面的处理);过滤通过后,拦截器将检查用户提交数据的验证,做一些前期的数据处理,接着把处理后的数据发给对应的Action;Action处理完成返回后,拦截器还可以做其他过程(还没想到要做啥),再向上返回到过滤器的后续操作。

一个Filter 可负责拦截多个请求或响应:一个请求或响应也可被多个请求拦截。

创建一个Filter 只需两个步骤:

(1)创建Filter 处理类:

(2)在web.xml 文件中配置Filter 。

创建Filter 必须实现javax.servlet.Filter 接口,在该接口中定义了三个方法。

• void init(FilterConfig config): 用于完成Filter 的初始化。

• void destroy(): 用于Filter 销毁前,完成某些资源的回收。

• void doFilter(ServletRequest request, ServletResponse response,FilterChain chain): 实现过滤功能,该方法就是对每个请求及响应增加的额外处理。 

 

过滤器Filter也具有生命周期:init()->doFilter()->destroy(),由部署文件中的filter元素驱动。在servlet2.4中,过滤器同样可以用于请求分派器,但须在web.xml中声明,<dispatcher>INCLUDE或FORWARD或REQUEST或ERROR</dispatcher>该元素位于filter-mapping中。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧农业是一种结合了现代信息技术,包括物联网、大数据、云计算等,对农业生产过程进行智能化管理和监控的新模式。它通过各种传感器和设备采集农业生产中的关键数据,如大气、土壤和水质参数,以及生物生长状态等,实现远程诊断和精准调控。智慧农业的核心价值在于提高农业生产效率,保障食品安全,实现资源的可持续利用,并为农业产业的转型升级提供支持。 智慧农业的实现依赖于多个子系统,包括但不限于设施蔬菜精细化种植管理系统、农业技术资料库、数据采集系统、防伪防串货系统、食品安全与质量追溯系统、应急追溯系统、灾情疫情防控系统、农业工作管理系统、远程诊断系统、监控中心、环境监测系统、智能环境控制系统等。这些系统共同构成了一个综合的信息管理和服务平台,使得农业生产者能够基于数据做出更加科学的决策。 数据采集是智慧农业的基础。通过手工录入、传感器自动采集、移动端录入、条码/RFID扫描录入、拍照录入以及GPS和遥感技术等多种方式,智慧农业系统能够全面收集农业生产过程中的各种数据。这些数据不仅包括环境参数,还涵盖了生长状态、加工保存、检验检疫等环节,为农业生产提供了全面的数据支持。 智慧农业的应用前景广阔,它不仅能够提升农业生产的管理水平,还能够通过各种应用系统,如库房管理、无公害监控、物资管理、成本控制等,为农业生产者提供全面的服务。此外,智慧农业还能够支持政府监管,通过发病报告、投入品报告、死亡报告等,加强农业产品的安全管理和质量控制。 面对智慧农业的建设和发展,存在一些挑战,如投资成本高、生产过程标准化难度大、数据采集和监测的技术难题等。为了克服这些挑战,需要政府、企业和相关机构的共同努力,通过政策支持、技术创新和教育培训等手段,推动智慧农业的健康发展。智慧农业的建设需要明确建设目的,选择合适的系统模块,并制定合理的设备布署方案,以实现农业生产的智能化、精准化和高效化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值