0.strut2入口:
通过web.xml配置全局过滤器,该过滤器类为
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter implements StrutsStatics, Filter
StrutsPrepareAndExecuteFilter 实现了javax.servlet.Filter这个接口,在Struts 2.1.3之前全局过滤器类 是 org.apache.struts2.disapatcher.FilterDispatcher
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
1.Struts2执行流程
页面请求(jsp) -> 拦截器栈(interceptorStack) ->业务控制器(Action) ->反向经过拦截器栈(interceptorStack)->
响应结果(jsp)
2.Action的使用
实现方式(a. 从com.opensymphony.xwork2.ActionSupport继承;b.实现com.opensymphony.xwork2.Action接口)
当然我们也可以不使用任何外来类,自己写一个类(类中需要一个execute方法)也是一样可以访问得到的,提供给我们的Action接口中只不过是存在几个常量,感兴趣的可以去看源码
配置Action(主要介绍动态方法调用 a.指定method b.感叹号 c.通配符方式)
<!-- 例如处理用户登录请求,action对应User_login 则去调用UserAction中的login方法 -->
<action name="*_*" method="{2}" class="com.lagersoft.action.{1}Action">
<result>/index.jsp</result>
<result name="error">/error.jsp</result>
<result name="success">/WEB-INF/{1}/{2}.jsp</result>
</action>
3.拦截器的使用
实现方式(a.从com.opensymphony.xwork2.interceptor.AbstractInterceptor继承;b.实现com.opensymphony.xwork2.interceptor.Interceptor接口)
从AbstractInterceptor继承需要实现intercept方法,而实现Interceptor接口则需要实现init,intercept,destroy三个方法,拦截器和Action之间执行
的顺序是是这样的:
这里举一个经典的例子来做说明(计算执行Action所花费的时间)
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
public class FirstInterceptor extends AbstractInterceptor {
@Override
public String intercept(ActionInvocation invocation) throws Exception {
//执行目标Action之前开始计时
long start = System.currentTimeMillis();
//invocation在执行invoke方法时开始执行拦截器栈中下一个拦截器,如果当前拦截器是最后一个拦截器的时候则开始执行Action result是执行Action返回的结果
String result = invocation.invoke();
//Action已经执行完毕了,准备响应结果给用户
long end = System.currentTimeMillis();
long time = end - start;
System.out.println("执行FirstAction所花费的时间:" + time + "ms");
return result;
}
}
然后
需要在struts.xml中来注册和使用该拦截器
<!-- 注册声明拦截器 -->
<!-- 在自定义interceptor并将其ref时, 系统会覆盖掉默认的interceptor-stack(defaultStack), 为了保证系统默认的defaultStack不受印象, 我们需要显式的将其引入 -->
<!-- 注意两个interceptor-ref的顺序, 顺序不同, 执行效果也不同: 先配置的先执行/后配置的先退出(先进后出) -->
<interceptors>
<interceptor name="timer" class="com.lagersoft.interceptor.FirstInterceptor"/>
<interceptor-stack name="myInterceptor">
<interceptor-ref name="timer"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<action name="*_*" method="{2}" class="com.lagersoft.action.{1}Action">
<result>/index.jsp</result>
<!-- 引用拦截器栈 -->
<interceptor-ref name="myInterceptor"></interceptor-ref>
</action>
4.Struts2&Servlet API(在Struts中灵活的传值)
a.通过com.opensymphony.xwork2.ActionContext对象 能拿到request,不能拿到response
ActionContext context = ActionContext.getContext();
Object get(String key) //取得HttpServletRequest中key的值
void put(String key, Object value) //设置HttpServletRequest中key的值为value
Map getSession() //获取封装了HttpSession的Map对象;
void setSession(Map session)//直接传入一个Map实例,将该Map实例里的key-value对转换为session的属性
b.通过实现org.apache.struts2.util.ServletContextAware; (Servlet上下文对象)
org.apache.struts2.interceptor.ServletRequestAware;(request对象)
org.apache.struts2.interceptor.ServletResponseAware;(response对象)
org.apache.struts2.interceptor.SessionAware;(session对象)
实现这些接口的Action 需要在Action中配置相应的属性接收这些对象
private ServletContext application;//Servlet上下文对象
private HttpServletRequest request;//request对象
private HttpServletResponse response;//response对象
private Map session;//session对象
public void setServletContext(ServletContext context) {
this.application = context;
}
public void setServletResponse(HttpServletResponse response) {
this.response = response;
}
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
public void setSession(Map<String, Object> session) {
this.session = session;
}
查看源码可以发现Aware系列的接口其实是一种拦截器,拦截器代码会在执行action之前执行,将相关的servlet对象
设置进来。即这种方式是与servlet API 耦合的,可以看到其中session是解耦合的。
c.通过org.apache.struts2.ServletActionContext 来获取
ServletContext servletContext = ServletActionContext.getServletContext();
HttpServletRequest servletRequest = ServletActionContext.getRequest();
HttpSession httpSession = servletRequest.getSession();
httpSession.setAttribute("key", "value");
HttpServletResponse servletResponse = ServletActionContext.getResponse();
PageContext pageContext = ServletActionContext.getPageContext();
虽然是使用静态方法获取的request、response,但仍然能保证获取到当前用户以及当前线程的request、response,不会发生混淆。
因为struts2使用ThreadLocal来维护当前线程的request、response等数据。这种方式与servlet API 耦合