Struts2 filter: source code parsing of StrutsPrepareAndExecuteFilter

Source: Internet
Author: User

Struts2 filter: source code parsing of StrutsPrepareAndExecuteFilter

The following is a part of resolution, which is being updated continuously...

Recently, I am reading struts2. On the Forum, someone analyzed the source code of StrutsPrepareAndExecuteFilter. I think this class is very core. I can see how struts2 converts parameters after intercepting user requests. As shown in the following figure, I will read the code of this class.
When using struts. configure a filter in xml to intercept user-initiated requests and perform some preprocessing, assign the request to the corresponding action according to the configuration file and assign values to the parameters in the request and the fields in the action. Now let's explain what has happened behind this.
In some blogs about struts2, the filter used is FilterDispatcher. We can see the following descriptions in this document:
Deprecated. Since Struts 2.1.3, use StrutsPrepareAndExecuteFilter instead or StrutsPrepareFilter and StrutsExecuteFilter if needing using the ActionContextCleanUp filter in addition to this one
The description of StrutsPrepareAndExecuteFilter is as follows:
Handles both the preparation and execution phases of the Struts dispatching process. This filter is better to use when you don't have another filter that needs access to action context information, such as Sitemesh.
These two instructions are not described too much. The code snippet for configuring the filter in Web. xml is as follows:
<Filter>
<Filter-name> struts2 </filter-name>
<Filter-class>
Org. apache. struts2.dispatcher. ng. filter. StrutsPrepareAndExecuteFilter
</Filter-class>
</Filter>
<Filter-mapping>
<Filter-name> struts2 </filter-name>
<Url-pattern>/* </url-pattern>
</Filter-mapping>
Filter
To build a Filter, you just need to implement the javax. servlet. Filter interface. This interface has three methods:
? Init (): This method is called when the container instantiates a filter. It is mainly designed to prepare the filter for processing. This method accepts an object of the FilterConfig type as input.
? DoFilter (): it is the same as a servlet that has a service () method (this method also calls doPost () or doGet () to process requests, the filter has a single method doFilter () used to process requests and responses (). This method accepts three input parameters: A ServletRequest, response, and a FilterChain object.
? Destroy (): As you imagine, this method performs any cleanup operations that may need to be performed before automatic garbage collection.
Source code analysis
As described in this document, use StrutsPrepareAndExecuteFilter instead or StrutsPrepareFilter and StrutsExecuteFilter. There are two fields in the condition class, which declare the instances of StrutsPrepareFilter and StrutsExecuteFilter respectively. Now let's take a look at the init method.
Init Method
Public void init (FilterConfig filterConfig) throws ServletException {
// A tool class with multiple initialization Methods centralized
InitOperations init = new InitOperations ();
Try {
// Wrap the javax. servlet. FilterConfig object
// Implements the getInitParameterNames () method again.
// Convert the returned value from the Enumeration type to the Iterator type
FilterHostConfig config = new FilterHostConfig (filterConfig );
// Initialize the log
Init. initLogging (config );
// The creation of Dispatcher contains two information: servletcontext, the configuration parameters of the interceptor
// Specify the Initialization Configuration File order.
Dispatcher dispatcher = init. initDispatcher (config );
Init. initStaticContentLoader (config, dispatcher );
// PrepareOperations prepare for Request Processing
Prepare =
New PrepareOperations (filterConfig. getServletContext (), dispatcher );
Execute =
New ExecuteOperations (filterConfig. getServletContext (), dispatcher );
// Which requests are filtered out and no interceptor is executed
This. excludedPatterns = init. buildExcludedPatternsList (dispatcher );
// Callback Method
PostInit (dispatcher, filterConfig );
} Finally {
Init. cleanup ();
}
}
The code for creating a dispatcher is as follows:
Private Dispatcher createDispatcher (HostConfig filterConfig ){
Map <String, String> params = new HashMap <String, String> ();
For (Iterator e = filterConfig. getInitParameterNames (); e. hasNext ();){
String name = (String) e. next ();
String value = filterConfig. getInitParameter (name );
Params. put (name, value );
}
Return new Dispatcher (filterConfig. getServletContext (), params );
}
Private void init_DefaultProperties (){
ConfigurationManager. addConfigurationProvider (new DefaultPropertiesProvider ());
}
DoFilter
DoFilter is the execution method of the filter. It intercepts the submitted HttpServletRequest request and the HttpServletResponse response. It is the core interceptor of strtus2. A simple analysis is as follows:
Public void doFilter (ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
Try {
// Set the character delimiter set
Prepare. setEncodingAndLocale (request, response );
// Create actioncontext
Prepare. createActionContext (request, response );
// Dispater has a static Threadlocal variable, saving a copy for each thread
Prepare. assignDispatcherToThread ();
If (excludedPatterns! = Null &&
Prepare. isUrlExcluded (request, excludedPatterns )){
Chain. doFilter (request, response );
} Else {
// If a file upload request is sent, It is encapsulated as MultiPartRequestWrapper.
// Otherwise: StrutsRequestWrapper
// After encapsulation, you can access actioncontext and use the OGNL expression.
Request = prepare. wrapRequest (request );
// No mapping will be created in the case of static resource requests
// Or unidentifiable requests for other servlets
ActionMapping mapping = prepare. findActionMapping (
Request, response, true );
If (mapping = null ){
// Tries to execute a request for a static resource
// I don't have a very emotional understanding of this.
Boolean handled =
Execute.exe cuteStaticResourceRequest (request, response );
If (! Handled ){
Chain. doFilter (request, response );
}
} Else {
// Process the request, read the configuration file, and use the reflection mechanism to generate an action proxy
Execute.exe cuteAction (request, response, mapping );
}
}
} Finally {
Prepare. cleanupRequest (request );
}
}
Reference: http://www.iteye.com/topic/829843
Http://hiyachen.blog.chinaunix.net
The code for creating an actioncontext for the request is as follows:
Public ActionContext createActionContext (
HttpServletRequest request, HttpServletResponse response ){
ActionContext ctx;
Integer counter = 1;
// I do not know how to use this counter.
Integer oldCounter = (Integer) request. getAttribute (CLEANUP_RECURSION_COUNTER );
If (oldCounter! = Null ){
Counter = oldCounter + 1;
}
ActionContext oldContext = ActionContext. getContext ();
If (oldContext! = Null ){
// Detected existing context, so we are probably in a forward
Ctx = new ActionContext (
New HashMap <String, Object> (oldContext. getContextMap ()));
} Else {
ValueStack stack = dispatcher. getContainer (). getInstance
(ValueStackFactory. class). createValueStack ();
// Stack. getContext () is a Map <String, Object>
// Dispatcher. createContextMap () encapsulates http request-related information
// For example: request, reponse, ServletContext, http parameters, session, application
// The so-called context can be considered as a collection class, saving the information related to the http request
Stack. getContext (). putAll (dispatcher. createContextMap (
Request, response, null, servletContext ));
// Here we can see what actioncontext contains:
// Request, reposne, session, parameters in application, and valuestack.
// You can obtain the corresponding data through OGNL.
Ctx = new ActionContext (stack. getContext ());
}

Request. setAttribute (CLEANUP_RECURSION_COUNTER, counter );
ActionContext. setContext (ctx );
Return ctx;
}

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.