Introduction to Struts2 and struts2
I have studied the SSH framework for a long time and have never summarized it systematically. Here I will briefly talk about Struts2.
Why use Struts2?
Here are some of the disadvantages of Servlet:
1. Configure each servlet in web. xml. If many servlets exist, the content of web. xml is too large.
2. This structure is not conducive to group development.
3. In servlet, The doGet and doPost methods have the HttpServletRequest and HttpServletResponse parameters. These two parameters are related to the container. To perform a unit test in the servlet, you must initialize these two parameters.
4. If a servlet contains many methods, it must be passed in the form of parameters and decomposed into each method.
While while and .... First, let's take a look at what Struts2 is.
Struts2 is a Web layer framework that complies with MVC.
Let's take a look at the Web-based MVC three-tier architecture:
This is the basic mode of the MVC three-tier architecture. The display layer in the three-tier architecture is a Web application with the B/S structure. MVC is Model, View, and Controller.
What's better about Struts2 as a Web-layer MVC framework? What is MVC in Struts2?
Struts2 uses a filter to intercept client requests. The client sends a request. After passing through the struts2 filter, the HttpServletRequest parameter and the HttpServletResponse parameter are encapsulated, And the request is assigned to the mapped Action using the java reflection mechanism. Switch to another Action or jsp page based on the execution result of the Action
The Action of Struts2 is decoupled from the Servlet API, so that you do not need to directly reference and use interfaces such as HttpServletRequest and HttpServletResponse in the Action. Therefore, the Unit Test of Action is simpler, and the powerful type conversion makes it easier for us to do a lot of repetitive work.
Let's take a look at the Struts2 schematic:
The specific process is roughly as follows:
1. The client sends a request to the Servlet container (such as Tomcat)
2. This request goes through a series of filters)
3. FilterDispatcher (out of date) is called. FilterDispatcher asks ActionMapper to determine whether to call an Action.
4. If the ActionMapper decides to call an Action, FilterDispatcher will hand over the request processing to the ActionProxy.
5. ActionProxy queries the framework Configuration file through Configuration Manager and finds the Action class to be called.
6. ActionProxy creates an ActionInvocation instance.
7. The ActionInvocation instance uses the naming mode for calling. Before and after the Action is called, the call of the relevant Interceptor (Intercepter) is involved. (AOP is used here. A series of interceptors are notifications, and the Action method is the starting point)
8. After the Action is executed, ActionInvocation is responsible for finding the corresponding return result based on the configuration in struts. xml. The returned result is usually a JSP or FreeMarker template to be represented (but not always, or another Action chain. You can use the tag inherited from the Struts2 framework in the Process of representation. ActionMapper needs to be involved in this process
All objects (actions, Results, Interceptors, etc.) in the above process are created through ObjectFactory.
FilterDispatcher is the filter of struts2 in the early stage. After 2.1.3, use StrutsPrepareAndExecuteFilter. StrutsPrepareAndExecuteFilter, prepare for the preparation of the import; execute indicates to filter, refers to the doFilter method, the request will be requested, forwarded to the corresponding action for processing.
The above is the basic principle of Struts2. The following describes the main aspects of Struts2: Interceptor, verification, type conversion, property-driven, model-driven, and OGNL.
Interceptor
Struts2 comes with up to 35 interceptors. For example, the input verification is handled by the validation Interceptor. If the interceptor is disabled, the input verification stops working. File Upload relies on the interceptor named fileUpload.
The default interceptor provided by Struts2 is sufficient to meet the needs of the vast majority of applications, but it can also be customized.
Custom interceptor
1. Compile a class to implement com. opensymphony. xwork2.interceptor. Interceptor.
2. Mainly implement the public String intercept (ActionInvocation invocation) throws Exception {} Method
3. After the interceptor is defined, register it in the configuration file:
<interceptors> <interceptor name=" interceptorName" class="className"/> </interceptors>
4. The action in the configuration file is used by <interceptor-ref name = "interceptorName"> </interceptor-ref>.
Note: Once a custom interceptor is used in an action, the default blocker does not work. Generally, the following methods should be used:
<interceptor-ref name="defaultStack"></interceptor-ref><interceptor-ref name=" interceptorName"></interceptor-ref>
You can use package to combine multiple volume classes.
Verify
Sometimes, data sent from the client needs to be verified. For example, on the login page, the authentication username cannot be blank, the password cannot be blank, and the length cannot be less than 6 digits.
There are several verification methods:
1. Programming Method
Verify all the methods in the methods class:
Steps:
A. the category class inherits ActionSupport.
B. overwrite the public voidValidate ()Method
C. In the validate method, write the code that does not meet the requirements and call the addFieldError (String fieldName, String errorMessage) of the parent class)
IfFieldError(Map storing error information) has any element, that is, the verification fails and the Action method is not executed. The Struts2 framework returns the result with name = input.
D. Use the struts2 label on the page specified by name = input to display the error message. <S: fielderror/>
Verify the method specified in the methods class:
The writing steps are the same as above. The verification method must be written as follows:
Public voidValidateXxx ()Xxx represents the name of the Action method to be verified, in which the first letter of the Action method name should be capitalized.
2. XML-based configuration file
① Verify all methods in the methods class:
In the actions class package, create a simple action class name-validation. xml, for example, the role class name to be verified is the UserAction UserAction-validation.xml, the content is as follows:
1 <? Xml version = "1.0" encoding = "UTF-8"?> 2 <! DOCTYPE validators PUBLIC 3 "-// OpenSymphony Group // XWork Validator 1.0.3 // EN" 4 "http://www.opensymphony.com/xwork/xwork-validator-1.0.3.dtd"> 5 <validators> 6 <field name = "username"> 7 <! -- Built-in validators are defined, in the default. xml file in the xwork-core.jar com. opensymphony. xwork2.validator. validators package --> 8 <field-validator type = "requiredstring"> <! -- Cannot be null or "" string, by default, the leading and trailing spaces are removed --> 9 <message> the user name cannot be blank </message> 10 </field-validator> 11 </field> 12 </validators>
② Verify the method specified in the methods class:
The name of the configuration file must be written with: Rule class name-action name (action name in the configuration file)-validation. xml such as UserAction-user_add-validation.xml
3. Custom XML-based validators
A. Write a class that inherits the FieldValidatorSupport class.
B. Write your verification logic in public void validate (Object object). If the verification logic does not meet the requirements, send a message to fieldErrors.
C. You must register the validator before using it.
Create a configuration file named validators. xml in the WEB-INF/classes directory with the following content:
<validators> <validator name="strongpassword" class="wz.validators.StrongPasswordValidator"/></validators>
D. You can use the 16 validators provided by Struts2 in the future.
Property-driven and model-driven
Property-driven
Condition:
1. The attributes of name on the page must be consistent with those in action.
2. The properties in Action must have the get and set methods.
3. Property-driven is implemented when these two conditions are met.
Process:
1. When all interceptors are executed, the current requested action is placed at the top of the object stack.
2. objects placed on the object stack have direct access to their attributes.
3. When the ParameterInterceptor interceptor is executed, all the attributes of the action are at the top of the stack.
4. You only need to assign values to the action attribute at the top of the stack.
5. The ParameterInterceptor interceptor completes this function.
Model-driven
Assume that you need to obtain more than 20 attributes in the background when completing a website function. If you use the attribute in action to get the value, you must write 20 attributes and their set and get methods in the action. This will cause the code structure in the action to be poor.
The model-driven solution solves this problem. Use the javaBean object to encapsulate request parameters, implement the ModelDriven interface, and define the model member fields.
For example:
1 public class ModelDriverAction extends ActionSupport implements ModelDriven<User>{ 2 private User model = new User(); 3 public User getModel() { 4 return this.model; 5 } 6 7 public String execute(){ 8 return "modeldriver"; 9 }10 }
When the browser submits a request for the current Action, it passes through the interceptor first. One of the interceptors is ModelDrivenInterceptor. From this source code, we can see that this interceptor is used to obtain the model driver that implements the action of the ModelDriver interface. Here is the user. Then, push the model driver to the top of the object stack. In this way, you can directly display and assign values through attributes.
Is it property-driven or model-driven?
(1) it is best to unify the driver model used by actions in the system, that is, either property-driven or model-driven.
(2) If the objects in the persistence layer in the DB correspond to the attributes in the form one by one, model-driven is used, and the code should be much more neat.
(3) If the attributes of a form are not one-to-one, the attribute driver should be used. Otherwise, your system must provide two beans and one corresponding data submitted by the form, another use and persistence layer.
Type conversion
From the perspective of property-driven, what if the property is not required to accept the String type but other types? Struts2 will perform automatic conversion.
Each input in the client form may be a String or a String array. On the server side, you must convert these String values to a specific data type before processing the request. The Parameters interceptor is responsible for ing request Parameters to Action attributes, it is a member of the ultstack interceptor stack. All request parameters are of the String type, but not all Action attributes are of the String type. Therefore, each non-String action attribute needs to be converted to the relevant request parameters. Some Struts2 can be converted automatically, while some code that needs to be written manually.
Method:
1. Write a class,InheritanceCom. opensymphony. xwork2.conversion. impl.Defatypetypeconverter
2. overwrite the public ObjectConvertValue(Map <String, Object> context, Object value, Class toType)
Context: context of the OGNL expression
Value: the actual value. All input is a String, but it is a String array.
ToType: Target type
3. Register a type converter
3.1 local type converter: only valid for the current Action
Specific practice: in a package with the same category class, create a name named "category class name-conversion. properties, add the following content to the file: field to be verified = full name of the validator class. Example: birthday = wz. convertor. DateConvertor
3.2 global converter: valid for all actions
Practice: Create a configuration file named "WEB-INF" under the xwork-conversion.properties/classes directory with the following content added: Target type full name = full name of the validator class. Example: java. util. Date = cn. itcast. convertor. DateConvertor
Note: If the conversion fails, the Struts2 framework looks for the result page of name = input.
OGNL
The OGNL expression is an Object-Graph Navigation Language. OGNL is an open-source project. By default, the OGNL expression language is used in struts2 to display data. This is the same as the el expression in serlvet.
When speaking of OGNL, you have to mention ValueStack. ValueStack is an interface. Using OGNL expressions in struts2 is actually a class that implements the ValueStack interface.OgnlValueStackThis class is the basis of OgnlValueStack. ValueStack runs throughout the lifecycle of an action. Each action instance has a ValueStack object. The current action object and other related objects are saved. Struts2 saves the ValueStack object in the request domain named struts. valueStack.
When struts accepts a request, it quickly creates ActionContext, ValueStack, and action. Then, the action is stored in ValueStack, so the instance variable of the action can be accessed by OGNL.
ActionContext. getContext () obtains the ActionContext object of the thread from ThreadLocal.
The actionContext object can be obtained.Context, Application, session, valueStack, and other objects. The last three are actually extracted from the context.
ActionContext member domainContextYesOgnlContextThe context object in ValueStack.
The context object stores map, ValueStack, and other objects such as request, session, application, parameters, and attr.
Relationship between context map and valueStack:
1. There is a key-value pair in the context, key = com. opensymphony. xwork2.util. ValueStack. ValueStack, value = valueStack, that is, valueStack
2. The member fields in valueStack include CompoundRoot root and OgnlCotext context ;. That's right. It's the context above.
3. The member domain context in ActionContext is the context above.
The following is the content of the context object in ActionContext. Pay attention to the address.
So much for now. Above