Struts2简单开发流程
来源:互联网 发布:整理数据 英语 编辑:程序博客网 时间:2024/06/06 03:47
- Struts1的执行流程是什么;
- Struts2的执行流程是什么;
- 我们的Action如何编写;
- Action的配置问题;
- Action中操作Servlet Api;
1. Struts1的执行流程
大致思路如下:
当web客户端的浏览器发出http请求,然后到达tomcat的web应用服务器,将http请求头封装成HttpServletRequest和HttpServletResponse对象,然后doPost(req,resp)或者doGet(req,resp)到Tomcat的Servlet容器的前端控制Servlet, 也就是ActionServlet; 然后在其service中会调用RequestProcessor的process()方法,在这个主要的方法中,
1;会通过方法 String path = processPath(request, response) 截取出URL,也就是struts-config.xml的action的path部分;
2;processLocale(request, response) 处理国际化用到的Local相关信息;
3;ActionMapping mapping = processMapping(request, response, path); 根据path从ModuleConfig中取出Action的东西封装成ActionMapping;
4;ActionForm form = processActionForm(request, response, mapping); 根据ActionMapping 中的name属性查找ActionForm, 如果要是配置了ActionForm,那么就到request或者session中查找,如果在这两个中都没有找到,那么就根据ActionForm的路径采用反射来创建出ActionForm,并根据scope值将其放入到request或者session中;
5;processPopulate(request, response, form, mapping); 主要是将表单的数据收集转型到ActionForm中,在这个过程中会用到一个一个第三方组件BeanUtils将Map的值(将表单中的数据放入map中了)根据ActionForm中的字段类型转好,再调用setter方法将其放入到ActionForm上;
6; Action action = processActionCreate(request, response, mapping); 根据Action的完整类名称(type)到一个Map中去找,如果没有找到,就用反射创建一个,再将创建好的Action的放到Map中,所以Struts1的Action是单例的存在线程安全问题;
7; ActionForward forward = processActionPerform(request, response, action, form, mapping); 执行我们自定义的Action的execute方法,并将ActionForward返回;
8;processForwardConfig(request, response, forward); 根据上面的ActionForm完成相应的转发和转向;
3. Struts2的大致执行流程
Struts2的中央控制器是StrutsPreparedAndExecuteFilter这个类就类似Struts1中的ActionServlet; 这个中央控制器会创建一个Action的代理对象,这个ActionProxy会做一系列的工作,然后再调用真正的Action上去;这个类中有一个主要方法:
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
1; ActionMapping mapping = prepare.findActionMapping(request, response, true); 取得ActionMapping;
2; 执行ExecuteOperators.execute.executeAction(request, response, mapping);
3; 在executeAction中会调用Dispatcher的serviceAction;execute.executeAction(request, response, mapping); 会调用一个很关键的方法:
ActionProxy proxy = getContainer().getInstance(ActionProxyFactory.class).createActionProxy( namespace, name, method, extraContext, true, false);
这个ActionProxy是生产的StrutsActionProxy的父类;同时;
在生成ActionProxy代理的方法中会创建一个关键类:DefaultActionInvocation
public ActionProxy createActionProxy(ActionInvocation inv, String namespace, String actionName, String methodName, boolean executeResult, boolean cleanupContext) { DefaultActionProxy proxy = new DefaultActionProxy(inv, namespace, actionName, methodName, executeResult, cleanupContext); container.inject(proxy); proxy.prepare(); return proxy; }
同时,会调用DefaultActionProxy类的prepare()方法;在这个方法中会调用ActionInvocation invocation的init()方法;
在init()方法中有两个关键步骤:
createAction(contextMap);
List interceptorList = new ArrayList(proxy.getConfig().getInterceptors());
interceptors = interceptorList.iterator();
先说第一个createAction(contextMap);
会调用ObjectFactory的buildAction方法
action = objectFactory.buildAction(proxy.getActionName(), proxy.getNamespace(), proxy.getConfig(), contextMap);
会采用反射机制创建出Action,并且把Action赋值给ActionInvocttion成员变量中
其次第二个关键步骤:拿到18个拦截器;也放到ActionInvocation的成员变量interceptors中
也就是,在创建这个ActionProxy的过程中干了两个比较重要的是,第一创建了一个ActionInvocation 并且将创建的Action和18个拦截器放入了ActionInvocation的成员变量中;
最后在Dispatcher中生成了ActionProxy;
4;在Dispatcher的serviceAction的方法中调用生成代理类(StrutsActionProxy)的execute()方法;在这个execute()方法中会执行一个关键的操作,ActionInvocation的invoke();
5;ActionInvocation的invoke(); 进而会执行ActionInvocation中已经装入成员变量的拦截器interceptors的intercept方法;invokeActionOnly()方法;在invokeActionOnly()方法中会调用invokeAction(getAction(), proxy.getConfig());调用Action方法,返回转向的字符串;然后还是在这个invoke()方法中进而执行executeResult(); 在executeResult()中最终又会通过Struts2的ObjectFactory objectFactory.buildResult(resultConfig, invocationContext.getContextMap()); 创建一个Result对象,然后在executeResult()中,执行Result的result.execute(this);转向或者重定向到相应的视图模块;
3、Struts2中的Action如何编写
在Struts1中,我们可以继承Action覆盖execute方法:
public class MyAction extends Action { @Override public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { }}
在Struts2中,我们有三种方法来开发自己的Action;
第一种:就是一个POJO类无需继承,无需实现任何接口和类,但是需要在类中添加execute方法就可以
public String execute(){return "success";}
第二种:通常实现com.opensymphony.xwork2.Action接口,并且实现的其execute方法,
public class LoginAction implements Action { private LoginForm loginForm; private LoginDao loginDao; @Override public String execute() throws Exception{ //以后使用Spring IOC实现; String result = loginDao.checkUser(loginForm); if(result!=null) return SUCCESS; return LOGIN; }}
第三种:还有一种方式是继承com.opensymphony.xwork2下的ActionSupport类,并覆盖其execute方法;
ActionSupport已经实现了Action接口, 还实现了Validateable接口,提供了数据校验功能。通过继承该ActionSupport类,可以简化Struts 2的Action开发。
总结:
struts2不要求我们自己设计的action类继承任何的struts基类或struts接口, 但是我们为了方便实现我们自己的action,大多数情况下都会继承com.opensymphony.xwork2.ActionSupport类,并重写此类里的public String execute() throws Exception方法。 因为此类中实现了很多的实用借口,提供了很多默认方法,这些默认方法包括国际化信息的方法、默认的处理用户请求的方法等,这样可以大大的简化Acion的开发。在action中并非一定需要execute方法,也可以指定自己需要的方法,action编写完毕后,就需要在struts.xml文件中编写配置文件了;
4.Action类的配置问题;
4.1 Action类配置涉及到几个关键属性如下:
- name : action的名字,用于匹配请求的url;
- class : Action实现类的完整类名;
method : 调用Action实现类中指定的方法;
4.2 Action配置通配符使用:
首先对 method 属性进行说明:
通常action的作用是完成一个功能点,但是例如CRUD这样的操作使用四个action类显然不划算,在struts 2中可以将这四个功能映射到一个action中进行处理,这里就需要使用method属性了。具体的做法是:在struts.xml配置文件中为一个action使用method属性和name属性指定不同别名,就可以实现CRUD映射到同一个action了。
import com.opensymphony.xwork2.ActionSupport;public class UserAction extends ActionSupport{ private static final long serialVersionUID = 1L; //查询 public String listUser() throws Exception { return SUCCESS; } //修改 public String updateUser(){ return SUCCESS; } //删除 public String deleteUser(){ return SUCCESS; } //添加 public String addUser(){ return SUCCESS; }}
<package name="user" namespace="/user" extends="struts-default"> <!-- name class method 识别同一个Action中的不同方法--> <action name="list_User" class="action.UserAction" method="listUser"> <result>/list_User.jsp</result> </action> <action name="add_User" class="action.UserAction" method="addUser"> <result>/add_User.jsp</result> </action> <action name="delete_User" class="action.UserAction" method="deleteUser"> <result>/delete_User.jsp</result> </action> <action name="update_User" class="action.UserAction" method="updateUser"> <result>/update_User.jsp</result> </action></package>
使用通配符映射的方式可以大大减少action的数量,所谓通配符就是使用,用于匹配0个或多个字符。在action的配置中,可以为name属性使用来匹配任意的字符。比如下面的配置:
<action name="*_*" class="action.{1}Action" method="{1}User"> <result>/{1}_{2}.jsp</result></action>
5. Action中操作Servlet Api
方法一: Struts2提供了一个ActionContext类,Struts2的Action可以通过该类来访问Servlet API。类中常用方法如下:
- Object get(Object
key):相当于HttpServletRequest的getAttribute(Stringname)方法。 - Map getApplication():返回一个Map对象,该对象模拟了该应用的ServletContext实例。
- static ActionContext getContext():静态方法,获取系统的ActionContext实例。
- Map getParameters():获取所有请求参数。类似于HttpServletRequest的getParameterMap().
- Map getSession():返回一个Map对象,该Map对象模拟了HttpSession实例。
- void setApplication(Map
application):传入一个Map的key-value,转换成application的属性名、属性值。 - void setSession(Map session):传入一个Map的key-value,转换成session的属性名、属性值。
方法二: Struts2提供如下几个接口(需要implements并实现方法):
- ServletContextAware:实现该接口的Action可以直接访问Web应用的ServletContext实例。
- ServletRequestAware:实现该接口的Action可以直接访问用户请求的HttpServletRequest实例。
ServletResponseAware:实现该接口的Action可以直接访问服务器响应的HttpServletResponse实例。
方法三: 使用ServletActionContext(工具类)访问Servlet API:
static PageContext getPageContext():取得Web应用的PageContext对象。
Static HttpServletRequest getRequest():取得Web应用的HttpServletRequest对象。
Static HttpServletResponse getResponse
():取得Web应用的HttpServletResponse对象。Static ServletContext getServletContext():取得Web应用的ServletContext对象。
- struts2简单开发流程
- Struts2简单开发流程
- 二、Struts2开发流程
- Struts2 开发流程
- Struts2 开发流程
- Struts2框架开发流程
- struts2 一般开发流程
- struts2项目开发流程
- struts2开发一般流程
- struts2开发流程
- struts2的开发流程
- struts2开发流程
- Struts2开发流程分析
- 【Struts2】开发流程
- struts2最简单调用流程
- struts2搭建开发流程要点
- struts2搭建开发流程要点
- Struts2的基本开发流程
- SSLContext 去除证书验证
- int a[60][250][1000]数组的遍历
- Mac环境下VMware Fusion虚拟机虚拟网卡的配置
- linux文件系统详解
- 2>&1 的用法说明。
- Struts2简单开发流程
- LLVM学习笔记(20)
- HTTP协议详解(真的很经典)
- hadoop之 hadoop 机架感知
- Kendo UI Grid中的动态数据(一)
- 简单的Servlet,tomcat启动将数据加载到内存中去
- PHP后台图片的等比缩放
- centos7 linux下安装gcc
- hibernate保存数据到mysql时的中文乱码问题!