Struts Source Code Research - Action-INPUT Attributes [Reserved]

xiaoxiao2021-03-06  20

Beginner struts, wrote a very simple application, the main functions and pages are as follows:

1. The homepage shows the link of "Add New User", click on the link to start a Forward action, page oriented to add users JSP page

2. Add users' JSP pages to enter "User Name" and "User Description"

3, the user is entered, the input data legitimacy check, check the pass, save the input information into the file (using the Properties class), then return home; check failed to return to add user page

4, data legitimacy check is divided into two, the first partial inspection conditions use the struts Validator, the inspection conditions are configured in Validator.xml; the second part checks in the actionform,

Check failed to place an error message into ActionerRORS, then return to the page to add the user and display the error message.

If the JSP page, the code written by the Actionform and the Action class has reference to the Struts-Example application, so the code is no longer listed, please see the code package in the attachment.

It is worth mentioning that during the development process, I have encountered a small problem because of this problem, leading to the search for the Struts source code, the process of finding the wrong cause of the planing.

This error occurs in the Struts configuration file, first listed the wrong profile as follows:

============================================================================================================================================================================================================= ==

"- // Apache Software Foundation // DTD Struts Configuration 1.1 // En"

"http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">

Name = "CreateUserform"

TYPE = "com.zchome.createuserform" />

Path = "/ welcome"

Type = "org.apache.struts.Actions.forwardAction"

Parameter = "/ jsp / welcome.jsp" />

Path = "/ docreateuser"

TYPE = "com.zchome.createuserac"

Name = "CreateUserform"

Scope = "request"

INPUT = "Createuser">

This Plugin Initialize Tiles Definition Factory. This Later Can Takes Some

Parameters Explained Here After. The Plugin First Read Parameters from Web.xml, Then

Overload The with parameters defined here. All Parameters is Optional.

The Plugin Should Be Declared in Each Struts-Config File.

- Definitions-Config: (OPTIONAL)

Specify Configuration File Names. There Can Be Several CommA

Separated File Names (Default: ??)

- Moduleaware: (optional - struts1.1)

Specify if the tiles definition factory is module aware. If true (default),

There Will Be One Factory for Each Struts Module.

IF False, There Will Be One Common Factory for All Module. In this Later Case, IT Is Still Needed to Declare One Plugin Per Module. The Factory Will B

Initialized with parameters found in the first initialized plugin (generally the

One associated with the default module.

True: One factory per module. (Default)

False: One Single Shared Factory for All Modules

- Definitions-Parser-Validate: (Optional)

Specify if Xml Parser SHOULD VALIDATE The TILES Configuration File.

True: Validate. DTD SHOULD BE Specified in File Header. (Default)

False: No Validation

Paths found in tiles definitions are relative to the main context.

->

Value = "/ Web-inf / tiles-defs.xml" />

Property = "pathnames"

Value = "/ Web-inf / validator-rules.xml, / web-inf / value.xml" />

============================================================================================================================================================================================================= == First describe the error background of the system:

1. From the homepage, click on the link to add the user's page.

2. Enter the error data defined in the Vlidator.xml file in the Add User page, pop up the JavaScript dialog, prompting the error is normal

3. Enter the legal data in the addition user page, and the data saves into the file and redirects to the home page.

4. In the addition of the illegal data defined in the ActionForm in the Add User page, the system should return to the page to add the user's page! ! !

OK, you will focus on this to see the definition of adding actions, as follows:

============================================================================================================================================================================================================= ==

Path = "/ docreateuser"

TYPE = "com.zchome.createuserac"

Name = "CreateUserform"

Scope = "request"

INPUT = "Createuser">

============================================================================================================================================================================================================= == From the definition of the above, if the Validate verifies error, Struts should redirect us to the URI defined by the INPUT domain, ie /jsp/createuser.jsp

It seems that there should be no problem, then take a look at the wrong information, as follows:

============================================================================================================================================================================================================= ==

Java.lang.illegalargumentexception: path createuser does not start with a "/" character

At Org.Apache.catalina.core.ApplicationContext.getRequestDispatcher (ApplicationContext.java: 1179)

At Org.apache.catalina.core.ApplicationContextFacade.GetRequestDispatcher (ApplicationContextFacade.java: 174)

At Org.Apache.struts.Action.RequestProcessor.doForward (RequestProcessor.java: 1062)

At Org.Apache.struts.tiles.tilesRequestProcessor.doForward (tilesRequestProcessor.java: 274)

At Org.Apache.struts.Action.RequestProcessor.InternalModuleLativeForward (RequestProcessor.java: 1012)

At Org.Apache.struts.tiles.tilesRequestProcessor.internalModuleLativeForward (TileSremeStProcessor.java: 345)

At Org.Apache.Struts.At Org.Java:980) at Org.Apache.Struts.At Org.Apache.Struts.At (requestProcessor.java: 255)

At Org.apache.struts.Action.ActionServlet.Process (ActionServlet.java: 1482)

At Org.Apache.struts.Action.ActionServlet.dopost (ActionServlet.java: 525)

. . . The following is omitted. . .

============================================================================================================================================================================================================= ==

The error message clearly, "createuser" this PATH should start with "/" character

To locate this error, start opening from the above error message, starting the Struts source requestProcessor.java, first come to this paragraph:

============================================================================================================================================================================================================= ==

Public class requestprocessor {

. . . . . .

Protected Boolean ProcessValidate (httpservletRequest Request,

HTTPSERVLETRESPONSE RESPONSE,

Actionform Form,

ActionMApping mapping)

THROWS IOException, servletexception {

IF (Form == Null) {

Return (TRUE);

}

// WAS this request cancelled?

IF (Request.GetaTribute (globals.cancel_key)! = null) {

IF (log.Indebugeload ()) {

Log.debug ("Cancelled Transaction, Skipping Validation");

Return (TRUE);

}

// Has Validation Been TURNED OFF for this mapping?

IF (! mapping.getvalidate ()) {

Return (TRUE);

}

// Call The Form Bean's Validation Method

IF (log.Indebugeload ()) {

Log.debug ("Validating Input Form Properties);

}

ActionMESSAGES ERRORS = form.validate (Mapping, Request);

IF ((ERRORS == Null) || Errors.iseMpty ()) {

IF (log.isticraceenabled ()) {

Log.Trace ("No Errors Detected, Accepting Input");

}

Return (TRUE);

}

// Special Handling for Multipart Request

IF (form.getMultipArtRequestHandler ()! = null) {

IF (log.isticraceenabled ()) {

Log.Trace ("Rolling Back Multipart Request");

}

Form.GETMULTIPArtRequestHandler (). rollback ();

}

// Has An Input Form Been specified for this mapping?

String infut = mapping.getinput ();

IF (Input == Null) {

IF (log.isticraceenabled ()) {

Log.Trace ("Validation Failed But no Input Form Available);

}

Response.Senderror (httpservletResponse.sc_internal_server_error,

Getinternal (). getMessage ("noInput",

Mapping.getpath ()));

Return (False);

}

// Save out to the Input Form if Possible in INPUT FORM IF POSSIBLE

IF (log.Indebugeload ()) {

Log.debug ("Validation Failed, Returning To '" Input "'");

}

Request.setttribute (globals.error_key, errors);

IF (ModuleConfig.getControllerConfig (). getInputforward ()) {

ForwardConfig Forward = mapping.findforward (Input);

ProcessForwardConfig (Request, Response, Forward);

} else {

INTERNALMODULATIVEFORWARD (INPUT, REQUEST, RESPONSE);

}

Return (False);

}

============================================================================================================================================================================================================= == In the error message, the method of INTERNALMODULATIVEFORWARD is mentioned, so it is highlighted to look at the last few lines of the above code, can be seen, if

ModuleConfig.getControllerConfig (). getInputforward () This method returns false, then InternalModuleReLATIVEFORWARD

This method will be called. What is inputforward? ModuleConfig is a Manager class that manages all configuration information, then moduleconfig.getControllerConfig ()

The method returned by this method is an instance of the CONTROLLERCONFIG, then InputForward is definitely a member variable of the ControllerConfig class.

Take a look at Struts-Config.xml, there is this tag, preliminary guessing controllerConfig should be a configuration class read this tag.

This tag should define some behavior of ActionServlet as Controller!

OK, then look at the CONTROLLLLLLLERCONFIG this class about some of the code about the member variable of the INPUTFORWARD, as follows:

============================================================================================================================================================================================================= ==

/ **

*

Should the input property of {@link actionconfig}

* Instances Associated with this module be treated as the module

* Name of a corresponding {@Link forwardconfig}. A false

* Value Treats The as a module-relative path (consistent * with the hard code Behavior of Earlier Versions of Struts.

*

* @since struts 1.1

* /

Protected Boolean InputForward = False;

Public Boolean getInputForward () {

Return (this.inputForward);

}

Public void setInputforward (Boolean InputForward) {

This.inputForward = INPUTFORWARD;

}

============================================================================================================================================================================================================= ==

Beginners understand, the original INPUTFORWARD this property default value is false, then the method described above is not configured.

ModuleConfig.getControllerConfig (). getInputforward () naturally returns false, bingo!

Then, you will transfer to this method of INTERNALMODULATIVEFORWARD. Look at the source code of this method, as follows:

============================================================================================================================================================================================================= ==

Protected Void InternalModuleRelanForward

String Uri,

HTTPSERVLETREQUEST REQUEST,

Httpservletresponse response

THROWS IOException, servletexception {

// Construct a Request Dispatcher for the specified path

URI = moduleconfig.getprefix () URI;

// DELEGATE The processing of this request // fixme - Exception Handling?

IF (log.Indebugeload ()) {

Log.debug ("Delegating Via Forward To '" URI "");

}

DOFORWARD (URI, REQUEST, RESPONSE);

}

Protected void Doforward

String Uri,

HTTPSERVLETREQUEST REQUEST,

Httpservletresponse response

THROWS IOException, servletexception {

// unwrap the Multipart Request, if There is one.

IF (Request InstanceOf MultipartRequestWrapper) {

REQUEST = ((MultipartRequestWrapper) .GetRequest ();

}

RequestDispatcher rd = getServletContext (). GetRequestDispatcher (URI);

IF (rd == null) {

Response.senderror

HttpservletResponse.sc_internal_server_error,

Getinternal (). getMessage ("RequestDispatcher", URI);

Return;

}

Rd.Forward (Request, Response);

}

============================================================================================================================================================================================================= ==

As can be seen from the above, this method is to transmit URI = moduleconfig.getprefix () URI; this Dongdong is transmitted to the DOFORWARD method.

And the method of DOFORWARD calls Javax.Servlet.ServletContext method getRequestDispatcher this method

Since the error message is a problem, it seems that this parameter URI is very important. It is very likely that this URI has happened to make an error.

OK, start to analyze this URI, start from the beginning, this URI is assigned:

URI = MODULECONFIG.GETPREFIX () URI

1. ModuleConfig.getPrefix () This method returns to ""

(This is given some init-params when defining an actionServlet in a web.xml file, then this prefix is ​​possible.

Not empty, here is no longer listed)

2, this URI on the right side of the code is the input from ProcessValidate, as follows:

String infut = mapping.getinput ();

This INPUT should be the action of the action defined in the struts-config.xml file, which is "createuser". If strut is further resolved, then this

INPUT should be further converted into "/jsp/createuser.jsp"

Ok, until this, can be seen, this URI is not "createuser", that is, "/jsp/createuser.jsp", then see the definition of the method of getRequestDispatcher,

Open the servlet's API documentation, you can see the following paragraph:

============================================================================================================================================================================================================= ==

Public RequestDispatcher

GetRequestDispatcher (Java.lang.String Path) Returns a RequestDispatcher Object That ACTS AS A Wrapper

For the resource located at the given path. a RequestDispatcher Object Can Be Used to Forward a Request

To the resource or to include the resource in a response. The resource can be dynamic or static.

The Pathname Must Begin with a "/" and is interpreted as relative to the current context root.

Use getContext to Obtain a RequestDispatcher for Resources in Foreign Contexts. This Method Returns Null

IF The servletcontext cannot return a requestDispatcher.

============================================================================================================================================================================================================= == Finally, there is a feeling of calling the cloud, because this or error message is really uniform! From this paragraph, we can conclude that the value of this variable of the URI

It is definitely "createuser" instead of "/jsp/createuser.jsp" we want. Why is this so? Obviously Struts-Config.xml configuration

Some still are not right, or what is missing. Thinking of this, very natural, think of this configuration item mentioned above, because from the literal meaning

It seems that the use of this configuration should be the value of INPUT into the corresponding value in Forward, and in ControllerConfig, this variable default value is

FALSE, so speculation will change it to TRUE?

In order to find the answer, turn the Struts-Example again (because the action in this example also defines the input), finally found the answer, and the previous guess

It is very energetic, as follows:

============================================================================================================================================================================================================= ==

============================================================================================================================================================================================================= == To this, the problem is resolved, the correct Action configuration can be as follows:

============================================================================================================================================================================================================= ==

1, do not use InputForward

Path = "/ docreateuser"

TYPE = "com.zchome.createuserac"

Name = "CreateUserform"

Scope = "request"

INPUT = "/ jsp / createuser.jsp">

2, use InputForward

Path = "/ docreateuser"

TYPE = "com.zchome.createuserac"

Name = "CreateUserform"

Scope = "request"

INPUT = "Createuser">

============================================================================================================================================================================================================= ==

Moreover, from the positioning of the problem, I have learned a trick, it is javax.servlet.RequestDispatcher:

RequestDispatcher rd = getServletContext (). GetRequestDispatcher (URI);

IF (rd == null) {

Response.senderror

HttpservletResponse.sc_internal_server_error,

Getinternal (). getMessage ("RequestDispatcher", URI);

Return;

}

Rd.Forward (Request, Response);

In the future, the page is redirected, as long as the relative URI is a given URI, no need to write a virtual directory name of the next layer or the URL itself.

转载请注明原文地址:https://www.9cbs.com/read-43438.html

New Post(0)