个人剖析,不喜勿喷
扫码关注公众号,不定期更新干活
在此申明本博文并非原创,原文:http://blog.csdn.net/lenotang/article/details/3336623,本文章是在此文章基础上进行优化。也谈不上优化,只是加上了点自己的想法
为什么会用到这两个jar包呢,因为我需要通过这个jar来解析xml配置文件。
``` <?xml version="1.0" encoding="utf-8"?>
```
``` org.zxh.action.loginaction ```
具体的是交由这个类的login(method)这个方法。这个方法会方法一个string类型的字符串,如果返回的是success就将页面重定向到index.jsp如果是login就重定向到login.jsp。这个配置文件就是这样的作用。因为是自己写的,所以这里并不会想struts框架那样封装了很多东西,这里只是为了让读者更加深入的理解struts的运行机制。
``` public class filterdispatcher implements filter{ @override public void destroy() { // todo auto-generated method stub } @override public void dofilter(servletrequest arg0, servletresponse arg1, filterchain arg2) throws ioexception, servletexception { // todo auto-generated method stub } @override public void init(filterconfig arg0) throws servletexception { // todo auto-generated method stub }
}
```
// 获得xml配置文件 string webrootpath = getclass().getclassloader() .getresource("struts.xml").getpath();
package org.zxh.util; import java.util.hashmap; import java.util.map; /** * 将action属性封装成类 * @author 87077 * */ public class actionconfig { //action 给别人调用的名字 private string name; //action对应程序中的action类 private string clazzname; //action中的方法 private string method; //返回结果不知一条 所以用map private map<string, string> resultmap = new hashmap<string, string>(); public actionconfig(){ } public actionconfig(string name , string clazzname , string method , map<string, string> resultmap){ this.name=name; this.clazzname=clazzname; this.method=method; this.resultmap=resultmap; } public string getname() { return name; } public string getclazzname() { return clazzname; } public string getmethod() { return method; } public map<string, string> getresultmap() { return resultmap; } public void setname(string name) { this.name = name; } public void setclazzname(string clazzname) { this.clazzname = clazzname; } public void setmethod(string method) { this.method = method; } public void setresultmap(map<string, string> resultmap) { this.resultmap = resultmap; } }
package org.zxh.util; import java.io.file; 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; /** * 采用dom4j解析xml配置文件 * * @author 87077 * */ public class configutil { /** * @param filename * 待解析的文件 * @param map * 存放解析的数据 */ public static void parseconfigfile(string filename, map<string, actionconfig> map) { saxreader reader = new saxreader(); try { document doc = reader.read(new file("d:\\zxh\\soft\\apache-tomcat-7.0.70\\apache-tomcat-7.0.70\\webapps\\mystruts\\web-inf\\classes\\struts.xml")); element root = doc.getrootelement(); list<element> list = root.selectnodes("package/action"); for (element element : list) { // 封装成actionconfig对象,保存在map中 actionconfig config = new actionconfig(); // 获取action中的值 string name = element.attributevalue("name"); string clazzname = element.attributevalue("class"); string method = element.attributevalue("method"); // 将值传入javabean中 config.setname(name); config.setclazzname(clazzname); // 如果没有设置执行method 执行默认的 if (method == null || "".equals(method)) { method = "execute"; } config.setmethod(method); // 继续向下获取action中的返回方法 list<element> resultlist = element.selectnodes("result"); for (element resultelement : resultlist) { string resultname = resultelement.attributevalue("name"); string urlpath = resultelement.gettexttrim(); if (resultname == null || "".equals(resultname)) { resultname = "success"; } config.getresultmap().put(resultname, urlpath); } map.put(name, config); } } catch (documentexception e) { // todo auto-generated catch block e.printstacktrace(); } } }
@override public void init(filterconfig arg0) throws servletexception { // todo auto-generated method stub 过滤器的初始化过程 // 获得xml配置文件 string webrootpath = getclass().getclassloader() .getresource("struts.xml").getpath(); // 将xml配置文件解析装在到map中 configutil.parseconfigfile(webrootpath, map); }
public void dofilter(servletrequest arg0, servletresponse arg1, filterchain arg2)
dofilter()方法类似于servlet接口的service()方法。当客户端请求目标资源的时候,容器就会调用与这个目标资源相关联的过滤器的 dofilter()方法。其中参数 request, response 为 web 容器或 filter 链的上一个 filter 传递过来的请求和相应对象;参数 chain 为代表当前 filter 链的对象,在特定的操作完成后,可以调用 filterchain 对象的 chain.dofilter(request,response)方法将请求交付给 filter 链中的下一个 filter 或者目标 servlet 程序去处理,也可以直接向客户端返回响应信息,或者利用requestdispatcher的forward()和include()方法,以及 httpservletresponse的sendredirect()方法将请求转向到其他资源。这个方法的请求和响应参数的类型是 servletrequest和servletresponse,也就是说,过滤器的使用并不依赖于具体的协议。
//针对http请求,将请求和响应的类型还原为http类型 httpservletrequest request = (httpservletrequest) arg0; httpservletresponse response = (httpservletresponse) arg1; //设置请求和响应的编码问题 request.setcharacterencoding("utf-8"); response.setcharacterencoding("utf-8");
//获取请求路径 string url = request.getservletpath();
//请求地址过滤,如果不是以.action结尾的 if(!url.endswith(".action")){ //不是.action的放行 arg2.dofilter(request, response); return ; }
//解析request路径 int start = url.indexof("/"); int end = url.lastindexof("."); string path=url.substring(start+1,end); //通过path去匹配到对应的actionconfig类。在这里已经解析到了所有的action的信息 actionconfig config = map.get(path); //匹配不成功就返回找不到页面错误信息 if(config==null){ response.setstatus(response.sc_not_found); return ; }
//通过actionconfig获取完成的类名字 string clazzname=config.getclazzname(); //实例化action对象,不存在的话就提示错误信息 object action = getaction(clazzname); if(action==null){ //说明这个action是错误的,在配置文件中没有占到对应的action类 response.setstatus(response.sc_not_found); return ; }
public static void requesttoaction(httpservletrequest request , object action )
class<? extends object> clazzaction = action.getclass(); //获取aciton中所有属性,从前台获取的值很多,只有action属性中有的才会进行反射赋值 field[] fields = action.getclass().getdeclaredfields();
//获取请求中的名字属性值 enumeration<string> names=request.getparameternames();
string name=names.nextelement(); boolean flag=false; //需要判断action属性中没有的而请求中有的我们不需要进行反射处理 for (field field : fields) { if(name.equals(field.getname())){ flag=true; } } if(!flag){ return; } string[] value=request.getparametervalues(name);
class<object> fieldtype=(class<object>) clazzaction.getdeclaredfield(name).gettype();
//通过反射调用该属性的set方法 string setname="set"+name.substring(0,1).touppercase()+name.substring(1); method method=clazzaction.getmethod(setname, new class[]{fieldtype});
private static object[] transfer(class<object> fieldtype , string[] value){ object[] os = null; //fieldtype 是[]这种类型的,需要将[]去掉 string type=fieldtype.getsimplename().replace("[]", ""); if("string".equals(type)){ os=value; }else if("int".equals(type)||"integer".equals(type)){ os = new integer[value.length]; for (int i = 0; i < os.length; i++) { os[i] = integer.parseint(value[i]); } }else if("float".equals(type)||"float".equals(type)){ os=new float[value.length]; for (int i = 0; i < os.length; i++) { os[i]=float.parsefloat(value[i]); } }else if("double".equals(type)||"double".equals(type)){ os=new double[value.length]; for (int i = 0; i < os.length; i++) { os[i]=double.parsedouble(value[i]); } } return os; }
//判断是否是数组属性 if(fieldtype.isarray()){ method.invoke(action, new object[]{object}); }else { method.invoke(action, new object[]{object[0]}); }
这说一下 method.invoke是将action类中method方法这个方法需要的参数就是object<a href="http://www.oschina.net/code/snippet_216465_36771”>详解
//前置拦截,获取request里面的参数,调用action的set方法给属性设置值 beanutil.requesttoaction(request, action);
private string executeaction(actionconfig config, object action) { string method = config.getmethod(); string result = null; try { method callmethod = action.getclass().getmethod(method,string.class); result = (string) callmethod.invoke(action, new object[] {}); } catch (exception e) { // todo auto-generated catch block e.printstacktrace(); } return config.getresultmap().get(result); }
request.getrequestdispatcher(result).forward(request, response);
<form method="post" action="login.action" name="loginform"> <table width="422" border="1" bgcolor="#0080c0" height="184"> <caption> <h1>用户登陆</h1> </caption> <tbody> <tr> <td> 姓名:</td> <td> <input type="text" name="username"> </td> </tr> <tr> <td> 密码:</td> <td> <input type="password" name="password"> </td> </tr> <tr align="center"> <td colspan="2"> <input type="submit" value="登陆" name="submit"> <input type="reset" value="重置" name="reset"> </td> </tr> </tbody> </table> </form>
如对本文有疑问, 点击进行留言回复!!
Springboot项目因为kackson版本问题启动报错解决方案
Java多线程下的其他组件之CyclicBarrier、Callable、Future和FutureTask详解
网友评论