自定义Struts2实现
来源:互联网 发布:淘宝少女心店铺 编辑:程序博客网 时间:2024/06/12 19:25
一:struts2运行机制:
Tomcat一启动,一些信息就已经加载完成,例如StrutsPrepareAndExecuteFilter加载的那些strut.xml以及Action的class类文件
1)客户端在浏览器中输入一个url地址,例如http://localhost:8080/user!findUser.do。
2)这个url请求通过http协议发送给tomcat。
3)tomcat根据url找到对应项目里面的web.xml文件。
4)在web.xml里面会发现有struts2的配置。
5)然后会找到struts2对应的struts.xml配置文件。
6)根据url解析struts.xml配置文件就会找到对应的class。
7)调用完class返回一个字String,根据struts.xml返回到对应的jsp。
二:struts2运行原理(网络摘抄)
上图来源于Struts2官方站点,是Struts 2 的整体结构。
一个请求在Struts2框架中的处理大概分为以下几个步骤:
1) 客户端初始化一个指向Servlet容器(例如Tomcat)的请求。
2) 这个请求经过一系列的过滤器(Filter)。
3) 接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请是否需要调用某个Action。
4) 如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy。
5) ActionProxy通过Configuration Manager询问框架的配置文件,找到需要调用的Action类。
6) ActionProxy创建一个ActionInvocation的实例。
7) ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。
8) 一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。
Struts2的核心就是拦截器。Struts.xml中所有的package都要extends="struts-default"。同理与所有的Java类都要extends自Object一样。struts-default.xml里面就是要做以上事情。
三:下面带大家自定义简单的实现一下struts2
1、创建存放解析struts后的文件,保存里面的name和class以及result结果的Map集合
package com.s.bean;import java.util.HashMap;import java.util.Map;public class ActionXml {//对应存放的nameprivate String name; //对应存放的classprivate String clazz;//对应存放的那些result,保存ResultXml bean结果private Map results = new HashMap();public String getName() {return name;}public void setName(String name) {this.name = name;}public String getClazz() {return clazz;}public void setClazz(String clazz) {this.clazz = clazz;}public Map getResults() {return results;}public void setResults(Map results) {this.results = results;}}
2、创建存放解析struts后的文件,保存里面的result文件信息
package com.s.bean;public class ResultXml {//名称private String name;//值private String value;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getValue() {return value;}public void setValue(String value) {this.value = value;}}
3、创建解析XML的类文件
package com.s.parse;import java.io.File;import java.util.HashMap;import java.util.List;import java.util.Map;import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.Element;import org.dom4j.io.SAXReader;import com.s.bean.ActionXml;import com.s.bean.ResultXml;public class ParseXml {private static Map<String,ActionXml> map = new HashMap<String,ActionXml>();public ParseXml(){}public static Map<String,ActionXml> getXML(){SAXReader sax = new SAXReader();Document doc = null;try {doc = sax.read(Thread.currentThread().getContextClassLoader().getResourceAsStream("struts.xml"));} catch (DocumentException e) {// TODO Auto-generated catch blocke.printStackTrace();}//得到根目录Element root = doc.getRootElement();//得到所有action配置List list = root.elements();for(Object obj : list){ActionXml ax = new ActionXml();Element a = (Element)obj;ax.setName(a.attributeValue("name"));ax.setClazz(a.attributeValue("class"));//得到所有resultList results = a.elements();for(Object obj1 : results){ResultXml rx = new ResultXml();Element r = (Element)obj1;rx.setName(r.attributeValue("name"));rx.setValue(r.getText());ax.getResults().put(rx.getName(), rx.getValue());}//将所有的action的配置读取出来,放入到一个MAP中map.put(ax.getName(), ax);}return map;}/** * @param args */public static void main(String[] args) {// TODO Auto-generated method stub ParseXml.getXML();}}
4、创建过滤器,tomcat启动后,struts.xml中的文件被解析,并且对应的class文件实体被创建,使用了反射,相当于struts2中的FilterDispatcher
package com.s.filter;import java.io.IOException;import java.io.PrintWriter;import java.lang.reflect.InvocationTargetException;import java.util.Map;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.s.bean.Action;import com.s.bean.ActionXml;import com.s.parse.ParseXml;import com.sun.org.apache.commons.beanutils.BeanUtils;public class DispatherFilter implements Filter { //专门放配置的mapprivate static Map<String ,ActionXml> map;public void doFilter(ServletRequest arg0, ServletResponse arg1,FilterChain arg2) throws IOException, ServletException {// TODO Auto-generated method stubHttpServletRequest request = (HttpServletRequest)arg0;//得到表单请求的名字,比如aString actionName = request.getRequestURI().split("/")[2].split("\\.")[0];//根椐表单请求的名字找到对应的处理类ActionXml ax = map.get(actionName);String clazz = ax.getClazz();String result = "";try {Class cla = Class.forName(clazz);Object obj = cla.newInstance();//根椐clazz产生接收和处理数据的对象//将表单中的数据交给该objBeanUtils.populate(obj, request.getParameterMap());Action action = (Action)obj;result = action.execute();//执行方法后得到result//根椐result找到对应的要跳转的界面String resultPage = (String)ax.getResults().get(result);//根椐结果页面跳转request.getRequestDispatcher(resultPage).forward(arg0, arg1);} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InstantiationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InvocationTargetException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public void destroy() {// TODO Auto-generated method stub}public void init(FilterConfig arg0) throws ServletException {// TODO Auto-generated method stubmap = ParseXml.getXML();//读取配置}}
4、定义一个Action的接口类,里面只有一个execute方法
package com.s.bean;public interface Action {public String execute();}
这样,一个小型的框架就完成了,它里面包含Tomcat启动后对struts.xml文件的解析,以及Action类的实体化,这样我们只要定义我们的action实现类和加入我们的struts.xml就可以灵活驾驭这个框架了。
5、定义struts.xml
<?xml version="1.0" encoding="UTF-8" ?><struts> <action name="a" class="com.s.bean.Users"> <result name='success'>/success.jsp</result> <result name='fail'>/fail.jsp</result> <result name='ok'>/ok.jsp</result> </action> </struts>
6、定义我们的Action的实现类
package com.s.bean;import java.io.Serializable;public class Users implements Serializable,Action{/** * */private static final long serialVersionUID = -4293478837686410970L;private int uid;private String uname;private String upwd;public int getUid() {return uid;}public void setUid(int uid) {this.uid = uid;}public String getUname() {return uname;}public void setUname(String uname) {this.uname = uname;}public String getUpwd() {return upwd;}public void setUpwd(String upwd) {this.upwd = upwd;}//处理数据的方法public String execute(){//在这里操作数据库if(uname.equals("admin")){ return "fail";}else{return "success";}}}
7、测试页面,或者使用超链接进行测试:http://localhost:8080/a.do?uname=aaa&upwd=bbb:
<form action="a.do" method="post"> username:<input type="text" name="uname"/><br> password:<input type="text" name="upwd"/><br> <input type="submit" value="提交"/> </form>
解析:
Tomcat已启动,DispatherFilter中的init方法得到执行,解析struts.xml文件,并把相应的信息保存在全局变量的map中
当用户通过超链接的方式访问http://localhost:8080/a.do?uname=aaa&upwd=bbb,转入到DispatherFilter,通过DispatherFilter解析超链接request.getRequestURI().split("/")[2].split("\\.")[0];,得到action中的name名称,然后通过parseXML类得到相对应的class类,然后利用反射机制创建它的实体,系统默认执行里面的execute方法,得到相应的字符串信息,根据返回的字符串信息,通过解析xml找到相应的结果页面,然后通过request.getRequestDispatcher(resultPage).forward(arg0, arg1);跳转到相应的页面,得到相应的结果
结合struts2原理,我们不然发现struts2中的FilterDispatcher相当与我们自定义的DispatherFilter,里面的ActionMapper就是我们自己定义的全局变量map,至于struts2中的ActionProxy,以及Configuration Manager,ActionInvocation and (Intercepter)我们这里就没有涉及了,用户可以自己依次去实现,这里只是简单的实现了一下struts2的原理,仅供学习参考!
源代码下载:http://download.csdn.net/detail/harderxin/5229826
- 自定义Struts2实现
- struts2 用户自定义实现国际化
- struts2实现自定义数据类型转换器
- struts2中实现自定义分页标签
- Struts2中实现自定义分页标签
- Struts2中实现自定义分页标签
- struts2自定义标签,实现权限认证
- Struts2自定义拦截器的实现
- 自定义实现struts2中的国际化机制
- struts2 自定义拦截器实现身份认证
- Struts2中实现自定义分页标签2
- Struts2 框架 自定义实现(一)
- Struts2自定义拦截器,实现登录检查。
- struts2中使用自定义标签实现翻页功能
- Struts2实现自定义转换器和全局类型转换器
- struts2自定义拦截器实现的分析说明附带代码
- Struts2 自定义拦截器 实现简单权限检查
- 使用struts2自定义拦截实现统一的身份验证模式
- cdecl、stdcall、fastcall函数调用约定区别
- C#设置richtextbox滚动到最后一行
- 编程珠玑第九章-代码优化 读书笔记
- nagios全攻略
- v$lock 和v$locked_object
- 自定义Struts2实现
- em与px的区别
- Linux共享库 LD_LIBRARY_PATH
- php高级工程师面试题收集
- HTML中 id 和name 的区别
- CI框架Email类配置腾讯邮箱失败
- sharepoint 2010 从PeopleEditor控件中取出多用户,并返回SPFieldUserValueCollection
- android数据库sqlite松散数据类型
- 2、OA实体设计(开篇)