A Brief introduction
Title, sometimes we need to be able to intercept requests before a request arrives at the controller, and filter or modify the parameters in the HttpServletRequest according to their specific circumstances. At this point, some students may think: can we in a filter will all the parameters in the HttpServletRequest to be filtered and then put back to the httpservletrequest?
> Obviously, in httpservletrequest it seems like only SetAttribute (String name, Object o) can set parameters, but we can find out after trying it: using SetAttribute ( The string name, Object O) method to reset the parameter is obviously not possible, because getting the parameter in the controller is essentially the public string getparameter of the ServletRequest called (string Name) or public string[] getparametervalues (String name) method, so you want to achieve the purpose of "modifying HttpServletRequest parameters in Filter", It is obvious that you need to use the adornment mode to write these methods in a row
Before the official code, I will briefly introduce the next ServletRequest, HttpServletRequest, Servletrequestwrapper and httpservletrequestwrapper The hierarchical relationships between these interfaces or classes, and explains " Inherit the Httpservletrequestwrapper class to implement modifying the HttpServletRequest parameter in the filter "What is the principle of this way?"
If we download Tomcat's source code from the Internet and look at it, we can clearly see the hierarchical relationship between these classes, and in Eclipse, the hierarchical relationship between them is this:
650) this.width=650; "src=" Http://s5.51cto.com/wyfs02/M02/8A/D0/wKioL1g85qyTt9gAAABZIaaToZg320.png "title=" 20160924212414740.png "alt=" Wkiol1g85qytt9gaaabziaatozg320.png "/>
If this chart is not clear enough, I have also drawn a simple UML structure diagram:
650) this.width=650; "src=" Http://s5.51cto.com/wyfs02/M00/8A/D0/wKioL1g85t-A2X73AABLKAbKiwo561.png "title=" 20160924212657710.png "alt=" Wkiol1g85t-a2x73aablkabkiwo561.png "/>
Note: Because I do not download a dedicated UML modeling tool now, I use the "paint" tool to simply draw a class diagram, and here Modifyparameterswrapper is a custom class I used to use later.
decorative mode :
Note: A standard decorative mode UML class diagram is this:
650) this.width=650; "src=" Http://s2.51cto.com/wyfs02/M01/8A/D0/wKioL1g85wehL7sOAAAShJLhnak171.png "title=" 20160924213704413.png "alt=" Wkiol1g85wehl7soaaashjlhnak171.png "/>
So the question is, how do I modify the parameters in the HttpServletRequest obtained in the background controller in filter?
A: It is very simple to customize a class in filter to inherit from the Httpservletrequestwrapper, and to replicate Getparameternames, GetParameter, Getparametervalues and other methods can
Two code implementation
(1) custom filter Modifyparametersfilter.java:
Package cn.zifangsky.filter;import java.io.ioexception;import java.util.enumeration;import java.util.Map;import java.util.Vector;import javax.servlet.FilterChain;import javax.servlet.servletexception;import javax.servlet.http.httpservletrequest;import javax.servlet.http.httpservletrequestwrapper;import javax.servlet.http.httpservletresponse;import Org.springframework.web.filter.onceperrequestfilter;public class modifyparametersfilter extends onceperrequestfilter {@Overrideprotected void dofilterinternal (httpservletrequest Request, httpservletresponse response, filterchain filterchain) throws servletexception, ioexception {modifyparameterswrapper mparameterswrapper = new Modifyparameterswrapper (request); Filterchain.dofilter (mparameterswrapper, response);} /** * inherits the Httpservletrequestwrapper, creating the adornment class to achieve the purpose of modifying the HttpServletRequest parameters &nbsP;*/private class modifyparameterswrapper extends httpservletrequestwrapper {private Map<String, String[]> parameterMap; // Map Collection of all parameters public Modifyparameterswrapper (httpservletrequest request) {super (request);p arametermap = Request.getparametermap ();} Rewrite methods in several httpservletrequestwrapper/** * get all parameter names * * @return return all parameter names */@Overridepublic enumeration<string> getparameternames () {Vector<String> vector = new Vector<String> (Parametermap.keyset ()); Return vector.elements ();} /** * gets the value of the specified parameter name, if there is a duplicate parameter name, returns the first value receives the generic variable , such as the text type * * @param name * specifying parameter names * @return Specify the value of the parameter name */@Overridepublic string getparameter (string name) {String[] Results = paRametermap.get (name);if (results == null | | results.length <= 0) return null;else {system.out.println (": before modifying" + results[0]); Return modify (Results[0]);}} /** * gets an array of all the values for the specified parameter name, such as: All data for the checkbox * receive array variable , such as CHECKOBX type */@ Overridepublic string[] getparametervalues (String name) {string[] results = parametermap.get (name);if (results == null | | results.length <= 0) return null;else {int length = results.length; for (int i = 0; i < length; i++) {system.out.println ("Modified before 2: " + results[i]); Results[i] = modify (Results[i]);} Return results;}} /** * a simple way to modify the original parameter, that is, to add a string that modifies the flag before the original parameter value * * @param string * Original parameter value * @return Modified value */private string modify (string string) {return " modified: " + string;}}}
The above code is simple, is to add an internal class: Modifyparameterswrapper, and then make a copy of the ServletRequest in a few ways, specifically, the original value of each parameter is preceded by the "Modified:" The string
(2) Register the filter in Web. xml:
<filter><filter-name>ModifyParametersFilter</filter-name><filter-class> cn.zifangsky.filter.modifyparametersfilter</filter-class></filter><filter-mapping>< filter-name>modifyparametersfilter</filter-name><url-pattern>/param/*</url-pattern><!- -Requests that come directly from the client and requests that come through forward are passed through the filter--><dispatcher>request</dispatcher><dispatcher> Forward</dispatcher></filter-mapping>
(3) Add a controller used by the test, i.e.: Testmodifycontroller.java:
Package Cn.zifangsky.controller;import Org.springframework.stereotype.controller;import Org.springframework.web.bind.annotation.requestmapping;import Org.springframework.web.bind.annotation.RequestParam; @Controllerpublic class Testmodifycontroller {@ Requestmapping ("/param/modify.html") public void Modify (@RequestParam ("name") String name) {System.out.println (" After modification: "+ name";}}
There is no complex logic to deal with, just simply output
(4) Test:
After you start the project, visit: HTTP://LOCALHOST:9180/FILTERDEMO/PARAM/MODIFY.HTML?NAME=ABC
As you can see, the output in the console is as follows:
Modified before 2:ABC modified: MODIFIED:ABC
This indicates that the filter we have previously customized has successfully modified the original parameters in HttpServletRequest. at the same time, it is also stated that Springmvc's @requestparam annotation essentially calls the Getparametervalues (String name) method in ServletRequest instead of GetParameter ( String name) method
Note: tomcat-8.5.5 Source: http://pan.baidu.com/s/1skWOso9
Reference article:
PS: The above image of the watermark is my personal blog domain name, so also please administrator mercy don't give me marked as "Reprint article", Thank you!!!
This article is from "Zifangsky's personal blog" blog, make sure to keep this source http://983836259.blog.51cto.com/7311475/1877592
Inherit httpservletrequestwrapper to implement parameters that modify HttpServletRequest in filter