Struts2 18 Interceptor (15th)

Source: Internet
Author: User
Tags expression engine

ParametersInterceptor the interceptor is at the position of defaultStack 15th. Here we skip an interceptor. First we will talk about ParametersInterceptor, and then we will talk about the third Interceptor. Because the blocker inherits from ParametersInterceptor, but the value assignment parameter source is different, it is easy to understand ActionMappingParametersInteceptor. The ParametersInterceptor interceptor inherits from MethodFilterInterceptor. Its main function is to set the Request Parameters in ActionContext to ValueStack. If the top of the stack is the current Action, the request parameters are set to Action, if the top of the stack is a model (the Action implements the ModelDriven Interface), the parameter is set to the model. The PrepareInterceptor mentioned above is also inherited from MethodFilterInterceptor. It was not explained at the time because the PrepareInterceptor does not perform method filtering in defaultStack, And the ParametersInterceptor interceptor does not filter methods in defaultStack, so for the moment, we will not talk about it in AnnotationValidationInterceptor. First, we will regard the doIntercept method of this interceptor as the previous intercept method. However, the interceptor configures request parameter filtering. The following are the parameter filtering parameters configured by the ParametersInterceptor interceptor in defaultStack: [html] <interceptor-ref name = "params"> <param name = "excludeParams"> dojo \.. *, ^ struts \.. * </param> </interceptor-ref> here, a parameter named excludeParams is passed, and its value is a regular expression separated by commas, the doIntercept method source code of the interceptor does not need to be set to ValueStack. [java] @ Override public String doIntercept (ActionInvocation invocation) throws Exception {Object action = invocation. get Action (); // get the currently executed Action object if (! (Action instanceof NoParameters) {// determines whether Action has implemented the NoParameters interface. If this interface is implemented, the Action does not have any request parameter ActionContext ac = invocation. getInvocationContext (); // obtain the final Map of the ActionContext Object <String, Object> parameters = retrieveParameters (ac); // obtain the request parameter Map // omitted... if (parameters! = Null) {// if the request parameter is not null Map <String, Object> contextMap = ac. getContextMap (); // get the context Map inside ActionContext, that is, the OgnlContext object try {// omitting... valueStack stack = ac. getValueStack (); // get the value stack setParameters (action, stack, parameters); // set the parameter for the value stack} finally {// omitted ...}}} return invocation. invoke (); // call the next interceptor} some non-important code is omitted in the above method. Is the remaining code very simple? The retrieveParameters method is used to obtain the request parameter Map. The following is the source code: [java] protected Map <String, Object> retrieveParameters (ActionContext ac) {return ac. getParameters () ;}// you do not need to explain the setParameters method as the main logic of the Interceptor. Now you can use this method: [java] protected void setParameters (Object action, ValueStack stack, final Map <String, Object> parameters) {ParameterNameAware parameterNameAware = (action instanceof ParameterNameAware )? (ParameterNameAware) action: null; // determines whether the Action has implemented the ParameterNameAware interface Map <String, Object> params; Map <String, Object> acceptableParameters; // valid parameter set // determines whether the parameter settings are ordered. The default value of ordered is false, that is, unordered if (ordered) {params = new TreeMap <String, Object> (getOrderedComparator ()); // obtain the comparator acceptableParameters = new TreeMap <String, Object> (getOrderedComparator (); params. putAll (parameters);} else {params = new Tree Map <String, Object> (parameters); acceptableParameters = new TreeMap <String, Object> () ;}// iteration request parameter for (Map. entry <String, Object> entry: params. entrySet () {String name = entry. getKey (); // determines whether the parameter is valid. If ParameterNameAware is implemented by Action, acceptableName (name) returns true and parameterNameAware. acceptableParameterName (name) // also returns true. This parameter is valid. If ParameterNameAware is not implemented for an Action, the value of this parameter is determined by the acceptableName (name) method. AbleName = acceptableName (name) & (parameterNameAware = null | parameterNameAware. acceptableParameterName (name); // if the parameter is valid, if (acceptableName) {acceptableParameters. put (name, entry. getValue (); // Add valid parameters to valid parameter sets} ValueStack newStack = valueStackFactory. createValueStack (stack); // omitted... for (Map. entry <String, Object> entry: acceptableParameters. entrySet () {// valid iteration parameter String name = entry. getKey (); // Parameter name Object value = entry. getValue (); // parameter value try {newStack. setValue (name, value); // set this parameter to ValueStack} catch (RuntimeException e) {// omitting ...}} // omit... // check that the method name adds valid parameters to ActionContext. However, in the interceptor, this method is empty and has no code. // This method is declared as protected, that is, subclass can override this method to change the behavior addParametersToContext (ActionContext. getContext (), acceptableParameters);} according to the preceding comments, you can find that the logic of the setParameters method is clear, that is, you can first determine whether the submitted parameter is legal, because the submitted parameters will affect the value stack, stru Ts2 checks the validity of submitted parameters to prevent malicious user attacks. The expressions in the request parameters contain equal signs (=), commas (,), and # signs (#) all are invalid expressions. Now let's take a look at how to determine whether a parameter is valid. As mentioned above, if the Action implements ParameterNameAware, you must determine the acceptableParameterName (name) method declared in the ParameterNameAware interface (implemented by logic) you also need to determine the acceptableName (name) method of the Interceptor. Let's assume that Action does not implement the ParameterNameAware interface, and whether the parameter is legal depends on the acceptableName (name) method. The following is the source code of this method: [java] protected boolean acceptableName (String name) {// call the isAccepted and isExcluded methods to determine if (isAccepted (name )&&! IsExcluded (name) {return true;} return false;} source code of isAccepted and isExcluded Methods: [java] protected boolean isAccepted (String paramName) {if (! This. acceptParams. isEmpty () {for (Pattern pattern: acceptParams) {Matcher matcher = pattern. matcher (paramName); if (matcher. matches () {return true;} return false;} else return acceptedPattern. matcher (paramName ). matches ();} protected boolean isExcluded (String paramName) {if (! This. excludeParams. isEmpty () {for (Pattern pattern: excludeParams) {Matcher matcher = pattern. matcher (paramName); if (matcher. matches () {return true ;}} return false;} As mentioned above, the interceptor configures parameter filtering and configures a parameter named excludeParams to specify which parameters need to be excluded, that is, it is invalid. When the string is passed, the interceptor parses the string and converts it to the corresponding Pattern object for regular expression verification, in the isAccepted and isExcluded methods, these regular expressions are used for testing. The logic is very simple. That's all. The interceptor also has an ordered attribute. The default value is false. The parameter is unordered when it is set to ValueStack. If ordered is set to true, the request parameters are sequentially set to ValueStack. Therefore, when creating a TreeMap, The getOrderedComparator () method is passed to the comparator object. The following is the source code of the getOrderedComparator () method: [java] protected Comparator <String> getOrderedComparator () {return rbCollator;} static final Comparator <String> rbCollator = new Comparator <String> () {public int compare (String s1, string s2) {int l1 = 0, l2 = 0; for (in T I = s1.length ()-1; I> = 0; I --) {if (s1.charAt (I) = '. ') l1 ++; // obtain the key of the request parameter through a loop '. 'Number of symbols} for (int I = s2.length ()-1; I> = 0; I --) {if (s2.charAt (I) = '. ') l2 ++; // obtain the key of the request parameter through a loop '. 'Number of symbols} return l1 <l2? -1: (l2 <l1? 1: s1.compareTo (s2) ;}; the rbCollator object is a comparator implemented using an anonymous internal class. We often write xxx When submitting request parameters. yyy. zzz = value, and the comparator includes 'according to the request parameter key '. 'Number of symbols for comparison ,'. 'The fewer symbols, the more advanced, that is '. 'The fewer symbols, the more you set them to ValueStack. This document also provides an example for you to take a look. The final parameter value assignment is the setValue method of the ValueStack called. This method is internally assigned by the OGNL Expression Engine, although it is very complicated internally, however, we only need to know that when the OGNL Expression Engine sets the request parameter to ValueStack, it is to search for objects with corresponding setter methods from the top of the stack to the bottom of the stack, if the value-assignment parameter finds an object with the setter method in ValueStack, the value of this parameter is assigned to the object. If the value is not found, the parameter is inherited to the bottom of the stack until it is found, if the bottom of the stack is not found, no value is assigned successfully.

Related Article

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.