1.1 Struts2概述
1.1.1 什么是Struts2
Struts2是由Apache社区的Struts1和Opensysmphony的Webwork整合而来,Struts负责对http请求的处理,Webwork负责业务逻辑处理。
1.1.2 运行环境搭建
1.导入13个jar包(在Struts2自带的demo中可以找到最少所需包)
2.需要在web.xml文件中配置StrutsPrepareAndExecuteFilter(ctrl+shif+t查找)
3.创建一个struts.xml文件,它的位置是可以放置在src下。(如果没有联网,需要配置约束,DTD映射类型为URL)
1.1.3 Struts执行流程
大致流程:
(1) 客户端(Client)向Action发用一个请求(Request)
(2) Container通过web.xml映射请求,并获得控制器(Controller)的名字
(3) 容器(Container)调用控制器(StrutsPrepareAndExecuteFilter)。在Struts2.1以前调用FilterDispatcher,Struts2.1以后调用StrutsPrepareAndExecuteFilter
(4) 控制器(Controller)通过ActionMapper获得Action的信息
(5) 控制器(Controller)调用ActionProxy
(6) ActionProxy读取struts.xml文件获取action和interceptor stack的信息。
(7) ActionProxy把request请求传递给ActionInvocation
(8) ActionInvocation根据配置文件加载相关的所有Interceptor拦截器,通过代理模式调用Action和interceptor
(9) 根据action的配置信息,产生result
(10) Result信息返回给ActionInvocation根据struts.xml中配置的result,决定进行下一步输出
(11) 产生一个HttpServletResponse响应
(12) 产生的响应行为发送给客服端。
详细流程:
1.启动服务器(tomcat),StrutsPrepareAndExecuteFilter的init方法执行将会自动加载配置文件
default.properties 在 struts2-core-2.3.7.jar 中 org.apache.struts2包里面(常量的默认值)
struts-default.xml 在 struts2-core-2.3.7.jar(Bean、273行18个默认拦截器、结果类型 )
struts-plugin.xml 在struts-Xxx-2.3.7.jar(在插件包中存在 ,配置插件信息 ) struts-config-browser-plugin-2.3.7.jar里面有
struts.xml 该文件是web应用默认的struts配置文件 (实际开发中,通常写struts.xml )
struts.properties 该文件是Struts的默认配置文件 (配置常量 )
web.xml 该文件是Web应用的配置文件 (配置常量 )
2.请求经过一系列的过滤器(Filter),StrutsPrepareAndExecuteFilter被调用doFilter方法被执行
HttpServletRequestrequest = (HttpServletRequest) req;
HttpServletResponse response =(HttpServletResponse) res;
prepare.setEncodingAndLocale(request,response);//设置编码格式:默认utf-8,根据
default.properties
prepare.createActionContext(request, response);//创建actionContext
prepare.assignDispatcherToThread();//整个的过程都在当前线程中执行
request =prepare.wrapRequest(request);//对request进行了包装
ActionMapping mapping = prepare.findActionMappin(request, response,true);//询问 ActionMapper来决定这个请求是否需要调用某个Action。如果是.action: dispatcher.serviceAction()
3.createAcitonContext(){
//利用容器创建值栈
ValueStack stack = dispatcher.getContainer().getInstance(ValueStackFactory.class).createValueStack();
//构建值栈的结构,把request,session,application等封装成一些map,再把这些map放入到 大map中
stack.getContext().putAll(dispatcher.createContextMap(request, response,null, servletContext));
//把大map的引用指向了ActionContext中的Map<String,Object> context;
ctx = new ActionContext(stack.getContext());
//把整个actionContext放入到了当前线程中,因为actionContext中有valueStack,所以 valueStack也在当前线程中,
//这样就保证了数据的安全性并且在一个线程范围内可以共享数据
ActionContext.setContext(ctx);
}
说明:
1、创建actionContext对象
2、创建ValueStack(实现类OnglValueStack)
3、把整个的actionContext放入到了ThreadLocal中
4.
serviceAction(){
ValueStack stack = (ValueStack)request.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
/**
* 因为在struts2容器中有太多的参数request,response,valueStack,session,application,paramters
所以struts2容器对当前的请求中用到所有的数据封装在了ActionContext中的map中
*/
extraContext.put(ActionContext.VALUE_STACK,valueStackFactory.createValueStack(stack));
String namespace = mapping.getNamespace();
String name = mapping.getName();
String method = mapping.getMethod();
//创建actionProxy
ActionProxy proxy =config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(
namespace,name, method, extraContext, true, false);
proxy.execute()方法
prepare.cleanupRequest(request);//把struts2过程中的数据全部清空了
}
5.在createActionProxy中执行了如下的内容:
重点:
执行了DefaultActionInvocation中的init方法
createAction(contextMap)调用ObjectFactory中buildAction 创建了action
s