Preface
I encountered such a problem in my work the day before yesterday. I encapsulated a pojo in the interface parameters. This is very common. When there are many parameters, the inertial thinking is to encapsulate a pojo. Then there are many annotations to add before the parameters, such as: @requestParam, @requestBody, @pathvariable, etc. My understanding is like this. First of all, I will state that I have never read the source code, but I just understand it based on experience. @requestParam is tried to use for get requests. The parameters are on the URL in the header of http. What is the specific place? The following exists in the form of key=value. @requestBody applies to post request parameters in http body. @pathvariable is more particularly the writing method of restful. Put parameters on the URL without question marks to distinguish whether it is a parameter or a URL. Maybe I'm not very accurate to say this. But I usually use it this way. At the same time, there is also a common way to write the parameters, which is to not add annotation before the parameters. For example, if the parameters are basic types, do not add @requestParam, and if the parameters are beans, do not add requestBody, they can also be parsed by springmvc. After my interface was seen by the team leader, he asked me to remove the @requestBody, because after adding this to the backend, the ajax request on the front end needs to display the statement content-type: "application/json" to be parsed by springmvc, which seems to have done something unnecessary. Although I removed it according to his requirements, I think I have to figure out what is going on, what is the difference between adding or not adding, what impact it has on performance, or the best applicable scenarios for each. In addition to Baidu, I also have to ask the masters.
Spring MVC interface parameter analysis process
First, I slowly studied the source code through debugging. Without adding any annotations:
During the development process, consumptions and produces are generally not added. It should be added accordingly, because it can reduce the search range of the interface. This is a simple demo, I just need him to check the process of springmvc receiving requests.
First, after tomcat is started, the request paths in all controller classes are @requestMapping and the Controller bean are loaded into the spring container. After the page request comes, the DispatcherServlet servlet is found. After the request comes to the servlet, everyone knows that there are two initialization methods of servlet. One is to load immediately, and the other is to load delayed. However, no matter what, the init method is only called once, and then the service method will be called directly every time. When tomcat is closed, the destroy method of the servlet ends. Therefore, springmvc encapsulation of servlet must inherit the service method, and the DispatcherServlet is also the doDispatch method. In this method, the request path is obtained by using the HttpServletRequest object, which is /notJson, and then compare it with all the URLs in the container to finally obtain the interface in the Controller. After finding the interface, you will naturally know the parameters of the interface. Here I am Display. For convenience and simplicity, there are only two parameters in Display, which are the two in the ajax request below.
springmvc will obtain the properties in pojo through reflection. In this process, springmvc will first declare an array. The size of this array is the number of parameters. I only have one here. In fact, I believe many people will encounter the same problem as me. When the parameters of bean and basic types exist at the same time, how will springmvc parse this? I have encountered this several times. Without looking at the source code, the basic types are also encapsulated into the bean, and the front-end will also write the attributes in an object. Of course I believe this is something that not everyone can accept. We all hope to figure out how it analyzes it, so that we can fiddle with it at that time. The following is the reflection process. After reflecting my pojo, I get the properties and methods inside. After parsing the parameters, assign values to the parameters. This is perhaps the most important place. How exactly is assigned?
From this method debug, I learned that name is display, which is the lowercase of the pojo class name. I don’t know why springmvc did this processing (see later). attribute is an object with age and name. But it's all null at this time. WebDataBinding is a special DataBinder used for data binding from web request parameters to JavaBean objects. Following up on the bindRequestParameters method, you will find a very familiar place when following it is the following figure. The parameter name is obtained by using String[] values = request.getParameterValues(paramName); This is the method of obtaining parameter of the servlet, so you can know the attribute name and attribute value of the requested parameter.
Next, it is conceivable that this parameter name is replaced with the attribute name of the bean, and the parameter name age is replaced with the attribute name age. Follow this place, the oragina is the property name value pair obtained by the serclet above, converting this map into PropertyValue here. (PropertyValue is an object that holds the information and values of a single bean property. Using an object here instead of just storing all properties in a map typed by the property name allows for more flexibility and the ability to handle indexed properties, etc. in an optimized way. Note that the value does not need to be the ultimate required type: the BeanWrapper implementation should handle any necessary transformations because this object has no idea which objects it will apply to.), so there are two PropertyValue objects.
When converting, you will ignore unknown attributes
The above picture shows the specific conversion method, which is relatively long. The following sentence directly assigns value to the bean. From this process. As long as the properties of the front-end json object are the same as the bean properties of the back-end, ajax does not write content-type, and uses the default application/x-www-form-urlencoded; charset=UTF-8 , you can directly assign values.
Summarize
The above is the entire content of this article. I hope that the content of this article has certain reference value for everyone's study or work. If you have any questions, you can leave a message to communicate. Thank you for your support to Wulin.com.