Configuration-based custom simple struts (Learn how struts works)

Source: Internet
Author: User

The configuration-based action jump mode of struts is particularly handy, and I also mimic struts ' action to implement a self-defined configuration file to configure the action for simple operations:

First, it can be known that the sturts is a filter to intercept requests sent by the browser, and then operate in the filter to implement this process.

So, we also define a filter in our program:

public class Strutsfilter implements filter{public     void DoFilter (ServletRequest arg0, Servletresponse arg1, Filterchain arg2) throws       IOException, servletexception {     {            }}


Likewise, all requests are intercepted and configured in Web. XML:

<?xml version= "1.0" encoding= "UTF-8"? ><web-app id= "Webapp_9" version= "2.4" xmlns= "Http://java.sun.com/xml/ns/j2ee" xmlns:xsi= "Http://www.w3.org/2001/XMLSchema-instance" Xsi:schemalo cation= "Http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" > <display-name >struts blank</display-name> <filter> <filter-name>struts2</filter-name> <f Ilter-class>com.yc.frame.filter.strutsfilter</filter-class> </filter> <filter-mapping> &    Lt;filter-name>struts2</filter-name> <url-pattern>*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list></we B-app> 
Of course The most important thing in struts is the Struts.xml configuration file, where the profiling configuration file can be known that struts must parse out the XML first, then the parsed XML is stored in a data structure, using reflection to find the corresponding action subclass, and then use reflection to activate the configuration of the method or the default EXE Cute method, since the logic comes out, then how to set the data structure of the XML parsed out of the file to store it?

Struts.xml as follows:

<?xml version= "1.0" encoding= "UTF-8"?><struts>  <!--custom Struts--    <package name= " Default "namespace="/"  >     <action name=" user.action "class=" Com.yc.frame.actions.UserAction "method=" Add ">            <result name=" Success "  type=" direct ">a.jsp</result>             <result name=" fail "type= "Direct" >a.jsp</result>     </action>    <!--multiple action-->    </package></ Struts>


Here, each node corresponds to a class, because the XML has a corresponding hierarchical relationship, so in the design of these classes, but also to reflect the hierarchical relationship of these classes, in order to accurately manipulate and manipulate the data:

The node class corresponding to the package node, which should have a collection of Actioin node classes <pre name= "code" class= "Java" > Nature to provide Getset method (Get,set omitted)

public class Packagewrapper implements serializable{/** * */private static final long Serialversionuid = 7700027765680530 207l;private String namespace;private map<string,actionwrapper> actionmap=new hashmap<string,actionwrapper > ();
}
The action node class, as well as the node collection of the result class,
<pre name= "code" class= "Java" > (Get,set omitted)


public class Actionwrapper implements serializable{
/**
*
*/
Private static final long serialversionuid = -4176005261524671229l;
Private String ClassName;
Private String MethodName;
Private map<string,resultwrapper> resultmap=new hashmap<string,resultwrapper> ();
}
Package com.yc.frame.wrapper;

Node class for the result node

public class Resultwrapper implements Serializable {

Private String type;
private String value;
Public String GetType () {
return type;
}
public void SetType (String type) {
This.type = type;
}
Public String GetValue () {
return value;
}
public void SetValue (String value) {
This.value = value;
}
Then, the nature of the first to save them, and then to operate, so, in the Init method of the filter is initialized to save well. Here is dom4j to his analysis: (parsing is omitted, there is a need to leave a message to the source!) )

The core of the link is to read out the action of the entity class, the use of reflection to find the corresponding method, the execution of the action method to get the return value, finally determine the type of result, the execution of the jump page, is not clear a bit?

1. Resolution Request HttpServletRequest request= (httpservletrequest) arg0; HttpServletResponse response= (httpservletresponse) arg1; String Servletpath=request.getservletpath ();//This is the requested resource path name//Determines whether the requested pathname is actionif (Servletpath.lastindexof (". Action" ) {==-1) {arg2.dofilter (request, response);} Else{try {//Address format: cccc/user.action/user.actionint lastslashindex = Servletpath.lastindexof ("/"); String requestactionname = servletpath.substring (Lastslashindex + 1); String namespacename = servletpath.substring (0,lastslashindex);//This is the folder address//2 after the total item. Find this in the map Actionpackagewrapper Packagewrapper = null;//todo://Why use this entry?for (map.entry<string, packagewrapper> Entry: Packagesmap.entryset ()) {Packagewrapper pw = entry.getvalue ();p w.getnamespace (). Equals (NamespaceName); Packagewrapper = Pw;break;} 3. Reflect the object that generated the action//4. Activates the Execute method of this action//5. Stringactionwrapper actionwrapper that this execute returns Packagewrapper.getactionmap (). get (Requestactionname); String actionclassname = Actionwrapper.getclassname (); Class C = class.forName (actionclassname); Object obj1=c.newinstance ();//todo://here Packagewrapper get a collection of interceptors list<interceptor> Interceptors=new arraylist<interceptor> (); List<interceptorwrapper> iw=packagewrapper.getinterceptorlist (); if (Iw.size () >0) {for (int i=0;i< Iw.size (); i++) {Interceptorwrapper interceptorwrapper=iw.get (i); String Inname=interceptorwrapper.getname (); String inclassname=interceptorwrapper.getclassname (); if (Inclassname.tolowercase (). EndsWith (Inname.tolowercase () + "Interceptor")) {Class interceptor = Class.forName (inclassname); Object obj=interceptor.newinstance (); Interceptors.add (((Interceptor) obj));}} Actioninvokation=new Actioninvokation (Interceptors, (Action) obj1);} string result = Invokeactionmethod (Request,c, requestactionname,actionwrapper);//6. To map to find the corresponding result of this string; Resultwrapper Resultwrapper=actionwrapper.getresultmap (). Get (Result),//7. Forward to this result on string dispatchertype= Resultwrapper.gettype (); String Page=resultwrapper.getvalue (); if (dispatchertype!=null&&! "". Equals (Dispatchertype)) {if ("direct". Equals (Dispatchertype)) {String path = Request.getcontextpath (); String basepath = request.getscheme () + "://" +request.getservername () + ":" +request.getserverport () +path+ "/"; Response.sendredirect (Basepath+page);}} Else{request.getrequestdispatcher (page). Forward (request, response);}} catch (Exception e) {e.printstacktrace (); Request.getsession (). SetAttribute ("Ycexeption", E.getmessage ());}}}  /** * This method activates the method in result by passing in the reflection instance and the name of the action and the method name obtained * @param c * @param requestactionname * @param actionwrapper * @return * @throws SecurityException * @throws nosuchmethodexception */private String Invokeactionmethod (httpservletre Quest Request,class c,string Requestactionname,actionwrapper actionwrapper) throws exception{string requestResult= "" Object obj=c.newinstance ();//This completes the working injectparametertoaction (request, obj, c) of the injected parameter, or//If MethodName is empty, Executes the Execute method in the action if (Actionwrapper.getmethodname () ==null| | "". Equals (Actionwrapper.getmethodname ())) {requestresult= (Action). Execute ();} else{//Otherwise the method of executing the configuration in action string Methodname=actionwrapper.getmethodname (); Method M=c.getmethod (methodName, null); requestresult= (String) m.invoke (obj, null);} return requestresult;} Injection parameters private void Injectparametertoaction (HttpServletRequest request,object obj,class c) throws Exception, Illegalaccessexception, IllegalArgumentException, invocationtargetexception{//basic types of injection//1. Remove all health-value pairs from the request and turn to map SetName map<string,string[]> map=parserequest (Request)//2. Find each method to inject from C Getmthod method name [] Ms=c.getmethods ();//3. Reverse activation method, injection parameter for (method M:ms) {String methodname=m.getname (); if (Map.containskey (MethodName)) {string[] values= Map.get (MethodName); if (values.length==1) {String s=values[0]; String type=m.getparametertypes () [0].getname (); if (M.getparametertypes () [0].getname (). Equals ("Java.lang.Integer" )|| M.getparametertypes () [0].getname (). Equals ("int")) {//Activate method, pass in value M.invoke (obj, Integer.parseint (s)); continue;} else if (M.getparametertypes () [0].getname (). Equals ("Java.lang.DoublE ") | | M.getparametertypes () [0].getname (). Equals ("Double")) {M.invoke (obj, double.parsedouble (s)); continue;} else if ( M.getparametertypes () [0].getname (). Equals ("Java.lang.Float") | | M.getparametertypes () [0].getname (). Equals ("float")) {M.invoke (obj, float.parsefloat (s)); continue;} else if ( M.getparametertypes () [0].getname (). Equals ("java.lang.String") | | M.getparametertypes () [0].getname (). Equals ("String")) {M.invoke (obj, s); continue;}}}} Private map<string, string[]> parserequest (httpservletrequest request) {map<string,string[]> Map=new Hashmap<string,string[]> (); Enumeration<string> Enu=request.getparameternames (); while (Enu.hasmoreelements ()) {String name= Enu.nextelement (); String methodname= "Set" +name.substring (0,1). toUpperCase () +name.substring (1); Map.put (MethodName, Request.getparametervalues (name));} return map;} public void init (Filterconfig config) throws servletexception {//read config file Struts.xml = "Maprealpath=config.getservletcont Ext (). Getrealpath ("/");p ackagesmap=Parsestrutsxml ();} 
parsing XML file omitted, this is my own implementation of one of the simplest struts, of course, powerful struts I just imitate the fur of fur, welcome to discuss and learn from each other.




Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Configuration-based custom simple struts (Learn how struts works)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.