The controller's method parameters in Springmvc can be integer,double, custom objects, Servletrequest,servletresponse,modelandview and so on, very flexible. This article will analyze how SPRINGMVC handles these parameters, allowing the reader to handle some of the custom parameters. Phenomenon The demo used in this article is based on Maven. Let's take a look at the corresponding phenomenon first. @Controller @requestmapping (value = "/test") public class TestController { @ Requestmapping ("/TESTRB") @ResponseBody public employee TESTRB (@RequestBody employee e) { return e; } @RequestMapping ("/testcustomobj") @ResponseBody public Employee Testcustomobj (Employee e) { return e; } @RequestMapping ("/TESTCUSTOMOBJWITHRP") & nbsp @ResponseBody Public employee TESTCUSTOMOBJWITHRP (@RequestParam employee e) { return e; } @RequestMapping ("/testdate") @ResponseBody Public date testdate (date date) { return date; } First this is a controller, there are 4 methods. Their corresponding parameters are custom objects with @requestbody, custom objects, custom objects with @requestparam, and date objects. NextWe do a one-way access to see how the corresponding phenomenon is. First First testrb: second testcustomobj: third testcustomobjwithrp: fourth testdate: Why the returned employee object will be automatically parsed into XML, please see the landlord's other blog: Poke me Why the employee parameters will be parsed, the employee parameters with @requestparam will not be parsed, or even error? Why can't the date type be parsed? What exactly does springmvc do with the parameters of these methods? @RequestBody, @RequestParam What is the difference between these two annotations? with these few questions. Let's start with the analysis. Source Analysis The source code analyzed in this article is spring version 4.0.2 before analyzing the source code, let us first look at the two important interfaces in Springmvc. Two interfaces corresponding to the processing of request method parameters, response return value processing, respectively, is handlermethodargumentresolver and Handlermethodreturnvaluehandler, Both of these interfaces are joined after the Spring3.1 version.   SPRINGMVC processing requests roughly like this: first intercepted by Dispatcherservlet, Dispatcherservlet obtains handlerexecutionchain through handlermapping, and then obtains Handleradapter. handleradapter the internal for each request, will instantiate a servletinvocablehandlermethod to handle, servletinvocablehandlermethod when processing, The request and response will be processed in two separate sections. After Handleradapter get Modelandview, then do the corresponding treatment. This article will focus on Servletinvocablehandlermethod's handling of requests and responses. 1. When the request is processed, it is based on the properties of the Servletinvocablehandlermethod ArgumentreSolvers (this property is defined in its parent class Invocablehandlermethod) is processed, Where the Argumentresolvers attribute is a Handlermethodargumentresolvercomposite class (a variant of the combined pattern is used here), This class is a class that implements the Handlermethodargumentresolver interface, which has a list of various handlermethodargumentresolver implementations. 2. When the response is processed, it is processed according to the Servletinvocablehandlermethod property Returnvaluehandlers (its own property). The Returnvaluehandlers property is a Handlermethodreturnvaluehandlercomposite class (a variant of the combined pattern is used here), This class is a class that implements the Handlermethodreturnvaluehandler interface, which has a list of various Handlermethodreturnvaluehandler implementations. The Returnvaluehandlers and Argumentresolvers properties of Servletinvocablehandlermethod are both assigned when the Servletinvocablehandlermethod is instantiated. (Use the Requestmappinghandleradapter property to assign a value). The Argumentresolvers and Returnvaluehandlers properties of Requestmappinghandleradapter are injected by the spring container when the requestmappinghandleradapter is instantiated. 。 where the default argumentresolvers: default returnvaluehandlers: we have learned in JSON, XML auto-conversion that article, With @responsebody annotations, the final return value is handled by the Requestresponsebodymethodprocessor Handlermethodreturnvaluehandler implementation class. We found through the source, ReQuestresponsebodymethodprocessor This class actually implements both the Handlermethodreturnvaluehandler and the Handlermethodargumentresolver interfaces. requestresponsebodymethodprocessor supported request types are controller method parameters with @requestbody annotations, The supported response type is the Controller method with @responsebody annotations. The specific handling of the requestresponsebodymethodprocessor response is to use a message converter. Use the internal Readwithmessageconverters method when processing the request. then executes the Readwithmessageconverters method of the parent class (Abstractmessageconvertermethodargumentresolver). Let's take a look at the commonly used Handlermethodargumentresolver implementation classes (in this paper, interested readers can do their own research). 1. requestparammethodargumentresolver supports parameters with @requestparam annotations or parameter 2 with Multipartfile types. requestparammapmethodargumentresolver support for parameters with @requestparam annotations && @RequestParam Annotation Properties value exists The && parameter type is the attribute 3 that implements the map interface. The pathvariablemethodargumentresolver supports parameters with @pathvariable annotations and if the parameter implements the map interface, the @PathVariable annotation needs to be 4 with the Value property. matrixvariablemethodargumentresolver supports parameters with @matrixvariable annotations and if the parameter implements the map interface, the @MatrixVariable annotation takes the Value property &nbsP;5. requestresponsebodymethodprocessor This article has analyzed 6. servletrequestmethodargumentresolver parameter types are implementation or inheritance or WebRequest, ServletRequest, Multipartrequest, HttpSession, Principal, Locale, TimeZone, InputStream, Reader, HttpMethod these classes. (This is why we add a httpservletrequest parameter to the controller's method, and spring gives us the reason to automatically get the HttpServletRequest object) 7. The servletresponsemethodargumentresolver parameter type is either implementation or inheritance or Servletresponse, OutputStream, writer, 8 of these classes. The redirectattributesmethodargumentresolver parameter is a class 9 that implements the Redirectattributes interface. The httpentitymethodprocessor parameter type is httpentity from the name we also see out, Ending with resolver is the class that implements the Handlermethodargumentresolver interface. Ending with processor is the class that implements the Handlermethodargumentresolver and Handlermethodreturnvaluehandler. Let's take a look at the common Handlermethodreturnvaluehandler implementation classes. 1. The modelandviewmethodreturnvaluehandler return value type is Modelandview or its subclass 2. The modelmethodprocessor return value type is model or its subclass 3. The viewmethodreturnvaluehandler return value type is view or its subclass 4. HttpheaThe dersreturnvaluehandler return value type is httpheaders or its subclass 5. The modelattributemethodprocessor return value has @modelattribute annotation 6. viewnamemethodreturnvaluehandler return value is void or string the rest of the readers who have not spoken can view the source code themselves. below begins to explain why these phenomena occur at the beginning of this article: 1. The first method TESTRB and the address http://localhost:8888/springmvcdemo/test/testrb?name=1&age=3 the parameter of this method uses the @requestbody, It has been analyzed before and processed by Requestresponsebodymethodprocessor. The contenttype then selects the appropriate message converter to read according to the HTTP request header. Obviously, our message converters have only the default ones that follow the JSON as well as the XML converters, and the passed parameters are name=1&age=3, with no content-type in the passed header, and the default is application/ Octet-stream, thus triggering the httpmediatypenotsupportedexception exception emancipation Scheme: We changed the transfer data to JSON, At the same time, the HTTP request Content-type changed to Application/json. Perfect solution. 2. Testcustomobj Method and Address http://localhost:8888/springmvcdemo/test/testcustomobj?name=1&age=3 This request will find servletmodelattributemethodprocessor this resolver. The default resolver has two servletmodelattributemethodprocessor, except that when instantiated, the property annotationnotrequired one is true,1 false. This servletmodelattributemethodprocessor processing parameter supports @mOdelattribute annotations, if the Annotationnotrequired property is true, the argument is not a simple type, so the Servletmodelattributemethodprocessor is selected, Finally, the employee object is instantiated by DataBinder and the corresponding property is written. 3. Testcustomobjwithrp Method and Address http://localhost:8888/springmvcdemo/test/testcustomobjwithrp?name=1&age=3 This request will find Requestparammethodargumentresolver (using the @requestparam annotation). Requestparammethodargumentresolver is obtained using Request.getparameter (parameter name), or Request.getparameter ("E") when processing parameters, It's obvious that our parameters are name=1&age=3. So getting null,requestparammethodargumentresolver processing missing value will trigger the missingservletrequestparameterexception exception. [Roughly speaking, interested readers please self-view source] Solution: Remove @requestparam annotations, let servletmodelattributemethodprocessor to deal with. 4. TestDate Method and Address http://localhost:8888/springmvcdemo/test/testdate?date=2014-05-15 This request will find Requestparammethodargumentresolver. Because this method is the same as the second method, there are two requestparammethodargumentresolver, and the attribute usedefaultresolution is different. Requestparammethodargumentresolver supports simple types, servletmodelattributemethodprocessor is support for non-simple types. The final step is the same as the third method, our parameter name is date, so we pass the Request.getparametER ("date") finds the date string (where the parameter name is not a date, then the final page is blank, because there is no @requestparam annotation, the argument is not required, Requestparammethodargumentresolver processing null value returns NULL). Finally, the appropriate property editor is found by DataBinder for type conversion. Finally, the constructor for the Java.util.Date object, public Date (String s), was found because the format we passed was not in the standard UTC time format, so the illegalargumentexception exception was eventually triggered. Solutions: 1. The format of the passed parameter is modified to the standard UTC time Format: Http://localhost:8888/SpringMVCDemo/test/testDate?date=Sat, 16:30:00 gmt 2. Add a custom property editor to the controller. @InitBinderpublic void Initbinder (Webdatabinder binder) { SimpleDateFormat DateFormat = new SimpleDateFormat ("Yyyy-mm-dd"); Binder.registercustomeditor (Date.class, New Customdateeditor (DateFormat, false));} This @initbinder annotation is injected into the webdatabinderfactory when the Servletinvocablehandlermethod is instantiated, And Webdatabinderfactory is a property of Servletinvocablehandlermethod. In the requestmappinghandleradapter source of 803 lines getdatabinderfactory is to get webdatabinderfactory. Requestparammethodargumentresolver created by Webdatabinderfactory after the WebdatabinderThe custom property Editor in the Customdateeditor to find the appropriate property editor (our custom property editor handles the date object with the TestDate parameter, which is exactly date), Finally Customdateeditor converts the string object to a Date object. Writing custom handlermethodargumentresolver through the previous analysis, we understand the SPRINGMVC process of handling the methods in the controller. Now, if there are two parameters in the method and are all custom class parameters, what should be handled? @RequestMapping ("/save") public Modelandview SaveAll (@FormModel employee employee, @FormModel Dept Dept, Modelandview view) { view.setviewname ("test/success"); view.addobject ("Employee", employee); View.addobject ("dept", Dept); return view; Let's try it. Obviously, to deal with this, you can only implement a class that implements Handlermethodargumentresolver. Source: http://www.2cto.com/kf/201405/301660.html
Spring MVC detailed