Struts2学习---拦截器+struts的工作流程+struts声明式异常处理

时间:2021-08-18 12:52:02

这一节我们来看看拦截器,在讲这个之前我是准备先看struts的声明式异常处理的,但是我发现这个声明式异常处理就是由拦截器实现的,所以就将拦截器的内容放到了前面。

这一节的内容是这样的:

  • 拦截器的介绍
  • 拦截器在struts中的地位
  • 拦截器的作用
  • 拦截器的配置(自定义拦截器)
  • 拦截器实现声明式异常处理

拦截器的介绍:

在看到拦截器的时候我的第一反应就想到了过滤器,在javaweb里面我们可以设置过滤器,request请求想要和服务区建立连接之前都要经过这个过滤器,然后才能访问到服务器。

同样的struts中也自带了一大堆拦截器,这些拦截器都默认的添加到了我们的action之前,在执行完我们自定义的action和result后又要经过这些拦截器。大概就像下图这样:

Struts2学习---拦截器+struts的工作流程+struts声明式异常处理

偷偷告诉你:在struts2中第一个拦截器就是异常拦截器,我怎么知道的?在struts2-core-2.3.34.jar/struts-default.xml文件中里面配置了各种拦截器,这些拦截器被放在一个栈中,打开这个文件你就能看到啦:

Struts2学习---拦截器+struts的工作流程+struts声明式异常处理

这个只是一部分,有兴趣的小伙伴可以自己去查看。

拦截器在struts中的地位:

在讲拦截器在struts地位之前我们有必要知道struts的工作流程(请允许我将struts官网上的流程图贴出):

Struts2学习---拦截器+struts的工作流程+struts声明式异常处理

下面是struts2的整体工作流程:

我们都知道当一个请求来的时候容器(服务器)会检查web.xml,我么在web.xml中配置了:org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter

这个类里面实现了一个过滤器,来完成一系列struts的操作。

在它的过滤器里面它调用了executeAction方法,然后在executeAction 中调用了dispatcher.serviceAction,然后在serviceAction中用

ActionProxy proxy = getContainer().getInstance(ActionProxyFactory.class).createActionProxy(namespace, name, method, extraContext, true, false);

来创建一个ActionProxy实例对象(这个是Action代理)

然后继续proxy.execute();执行这个实例对象的execute方法。

这个proxy对象其实是StrutsActionProxy的实例对象

execute方法会返回一个 return invocation.invoke();

这个其实就是在调用ActionInvocation中的invoke方法。

这个invoke就是用来调用拦截器的。

Struts2学习---拦截器+struts的工作流程+struts声明式异常处理

最后画的不太好,最后ActionInvocation每次调用完一个拦截器的时候拦截器都会掉用invoke重新调用ActionInvocation的intercept方法调用下一个拦截器。

所以现在大概明白了struts的大概工作流程了吧,然后拦截器在struts中的地位我想也就不需要我多说了。

拦截器的作用有:

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

通过上面的介绍,我们会发现struts的大部分功能都是由拦截器完成的有木有?

拦截器的配置(自定义拦截器):

接下来我们着手配置一个自定义的拦截器:

	<package name="test" namespace="/" extends="struts-default">
<interceptors>
<interceptor name="myInterceptor" class="TestStruts1.MyInterceptor"></interceptor>
</interceptors> <action name="test" class="TestStruts1.TestAction">
<result>/test.jsp</result>
<interceptor-ref name="my"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
</package>
<interceptor-ref name="defaultStack">上面一定要重写这句,因为我们自定义拦截器会覆盖掉原来默认的拦截器,所以要在我们定义的引用下面重新引用默认拦截器。

这个是对指定的action设置拦截器,如果想要设置一个全局拦截器怎么办?

在struts.xml里面定义全局的配置设置(这里配置的是拦截器栈)
<package name="xxx" extends="struts-default">
<interceptors>
<interceptor-stack name="myStack">
<interceptor-ref name="myInterceptor">
<param name="uncheckedValue">0</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="myStack"/>(这句是设置所有Action自动调用的拦截器堆栈)
</package> 然后在另一个包下配置action就行了:
<package name="LogonAdmin" extends="xxx">(这里继承xxx里面定义的配置就可以了)
然后在这里定义action
</package>

然后接着是写拦截器类,我们只要实现拦截器接口就行了:

public class MyIntercept implements Interceptor {

    public void init() {}
public void destroy() {} public String interceptor(ActionInvocation action) throws Exception{
//进行拦截操作
//可以写其他业务代码,例如session验证,字符编码的设置等。
//如果没有异常则调用ActionInvocation对象,让其继续调用其他拦截器
return action.invoke();
}
}

这样我们的拦截器就学习完毕了。

这样我们继续看看struts的声明式异常处理:

对单个action进行声明:

<package name="xxx" extends="struts-default">
<action name="" class=">
<result name="success">success.jsp</result>
<result name="sql">/sqlError.jsp</result> <exception-mapping result="sql" exception="java.sql.SQLException"></exception-mapping>
</action>
</package>

下面的是全局配置:

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

		<global-results>
<result name="error">/error.jsp</result>
</global-results> <global-exception-mappings>
<exception-mapping result="error" exception="java.lang.Exception"></exception-mapping>
</global-exception-mappings>
</package> <package name="admin" namespace="/admin" extends="error_default" >
<action name="index">
<result>/admin/index.html</result>
</action> </package>

这样就在用于异常捕获的拦截器里面对我们的异常进行处理了。

如有错误欢迎指正。