您的位置:首页 > 编程语言 > Java开发

struts拦截器和action

2015-10-06 09:05 507 查看
学习java EE开发有一段时间了,但感觉看到后面,又忘了前面,真心感觉必须得写点东西来复习一下了,首先还是从最基础的部分写起吧。本文主要介绍的是struts拦截器的简单例子结构。


首先简单回顾一下struts框架的处理历程见下图。



a) 客户端初始化一个指向Servlet容器的请求;

b) 根据Web.xml配置,请求首先经过ActionContextCleanUp过滤器,其为可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助(SiteMesh Plugin),主要清理当前线程的ActionContext和Dispatcher;

c) 请求经过插件过滤器,如:SiteMesh、etc等过滤器;

d) 请求经过核心过滤器FilterDispatcher,执行doFilter方法,在该方法中,询问ActionMapper来决定这个请求是否需要调用某个Action;

e) 如果ActionMapper决定需要调用某个Action,则ActionMapper会返回一个ActionMapping实例(存储Action的配置信息),并创建ActionProxy(Action代理)对象,将请求交给代理对象继续处理;

f) ActionProxy对象根据ActionMapping和Configuration Manager询问框架的配置文件,找到需要调用的Action类;

g) ActionProxy对象创建时,会同时创建一个ActionInvocation的实例;

h) ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用;

i) 一旦Action执行完毕,ActionInvocation实例负责根据struts.xml中的配置创建并返回Result。Result通常是一个需要被表示的JSP或者FreeMarker的模版,也可能是另外的一个Action链;

j) 如果要在返回Result之前做些什么,可以实现PreResultListener接口,PreResultListener可以在Interceptor中实现,也可以在Action中实现;

拦截器一般在action里面进行配置,共同存在配置文件struts.xml里面,其作用主要是对请求进行过滤和传参。当请求struts2的action时,Struts 2会查找配置文件,并根据其配置实例化相对的 拦截器对象,然后串成一个列表,最后一个一个地调用列表中的拦截器。Struts 2中已经定义了默认的拦截器栈,其定义在struts-default.xml中,其中默认的拦截器有18个,框架访问action的异常处理,配置信息处理,转发重定向选择,上传等。拦截器一般都要实现com.opensymphony.xwork2.interceptor.Interceptor接口或继承AbstractInterceptor,其中

void init();

void destroy();

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

package interceptor;

import com.opensymphony.xwork2.ActionInvocation;

import com.opensymphony.xwork2.interceptor.Interceptor;

public class MyInterceptor implements Interceptor {

public void destroy() {

// TODO Auto-generated method stub

}

public void init() {

// TODO Auto-generated method stub

}

public String intercept(ActionInvocation invocation) throws Exception {

System.out.println(“Action执行前插入 代码”);

//执行目标方法 (调用下一个拦截器, 或执行Action)

final String res = invocation.invoke();

System.out.println(“Action执行后插入 代码”);

return res;

}

}

Struts2拦截器需要在struts.xml中声明,如下struts.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.objectFactory" value="spring" />
<package name="default" extends="struts-default">
<interceptors>
<interceptor name="MyInterceptor" class="interceptor.MyInterceptor"></interceptor>
<interceptor-stack name="myInterceptorStack"> <!--定义自己的拦截器栈-->
<interceptor-ref name="MyInterceptor"/>
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
</interceptors>
<action name="loginAction" class="loginAction">
<result name="fail">/index.jsp </result>
<result name="success">/success.jsp</result>
<interceptor-ref name="myInterceptorStack"></interceptor-ref>
</action>
</package>
</struts>


3,action中的执行方法

Action中默认的执行方法是execute方法,这个方法执行请求,然后转向其他的页面,这是常规的做法,但有时候我们不想用这个方法名,为了代码的可读性,我们希望让他执行我们自己定义的方法,下面我们就来看一下执行其他方法的两种方法:

<action name="LoginAction" class="com.bzu.action.LoginAction" method="login">

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

<result name="fail">fail.jsp</result>

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

</action>

<action name="RegisteAction" class="com.bzu.action.LoginAction" method="registe">

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

<result name="fail">fail.jsp</result>

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

</action>


2.DMI(动态直接调用)这种方法,不需要进行struts.xml的配置。而是在html或者jsp页面中通过标示符号指定了要调用的方法。 关键的标示符号为”!”号,具体看一下下面表单:



">
<s:actionerror/>

username:<s:textfield name="username"></s:textfield>

password:<s:password name="password"></s:password>

<s:submit value="提交"></s:submit>

</s:form>


3.提交按钮指定提交方法,普通的提交按钮我们会这么写:

当我们想提交到我们指定的方法时我们可以在这个标签里添加一个method属性指定要提交的方法,如下:

<
bbba
span class="hljs-tag"><s:submit value="提交" method="login"></s:submit>


4.使用通配符配置Action,这种方法可以解决action配置文件混乱的问题,减少action的配置:

">
<result name="success">/WEB-INF/jsp/{1}_success.jsp</result>

</action>

<span style="font-size:18px;"><span style="color:#000000;">   </span></span>


在name属性的值后面加上*,意思是只要你请求的action名字以helloworld开头,本action就是你找的action,然后method是大括号加上1,这个1代表第一个星号的值,这样就可以动态执行请求的方法。

获取servletAPI的主要2种方法:

ActionContextcontext=ActionContext.getContext(); --得到Action执行的上下文

Maprequest=(Map)context.get("request");--得到HttpServletRequest的Map对象

Mapsession=context.getSession();--得到HttpSession的Map对象

Mapapplication=context.getApplication();--得到ServletContext的Map对象


Action类还有另一种获得ServletAPI的解耦方式,这就是我们可以让他实现某些特定的接口,让Struts2框架在运行时向Action实例注入request、session和application对象。这种方式也就是IOC(控制反转)方式,与之对应的三个接口和它们的方法如下所示:

public class SampleAction implementsAction,

RequestAware, SessionAware, ApplicationAware

{

private Map request;

private Map session;

private Map application;

@Override

public void setRequest(Map request)

{this.request = request;}

@Override

public void setSession(Map session)

{this.session = session;}

@Override

public void setApplication(Map application)

{this.application = application;}

}


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: