springmvc Request Binding Annotation Details

One

@RequestMapping

RequestMapping is an annotation used to process the request address mapping and can be used on classes or methods. For classes, the address is used as the parent path for all methods in the class that respond to requests.

The RequestMapping annotation has six attributes, which we will describe in three categories.

1, value, method;

value: Specify the actual address of the request, which can be in URI Template mode (described later).

Method: Specify the method type of request, GET, POST, PUT, DELETE, etc.

2, consumes,produces;

consumes: Specify the Content-Type (application/json, text/html) for processing requests;

produces: Specifies the content type returned, which is returned only if the type in the request request request header contains the specified type;

3, params,headers;

params: Specify that the request must contain some parameter values to be processed by this method.

headers: The specified request must contain some specified header value in order for this method to process the request.

Note:

The uri value of value falls into three categories:

A) Can be specified as a common specific value;

B) Can be specified as a class of values containing a variable (URI Template Patterns with Path Variables);

C) Can be specified as a class of values containing regular expressions (URI Template Patterns with Regular Expressions);

 

Two

The commonly used annotations for handler method parameter binding are divided into four categories according to the different parts of the Request they handle: (mainly about common types)

A. Processing the annotation of the requet uri part (referring to variable in uri template, excluding queryString part): @PathVariable;

B. Notes for processing the request header section: @RequestHeader, @CookieValue;

C. Notes for handling the request body section: @RequestParam, @RequestBody;

D. Processing attribute s is annotated: @SessionAttributes, @ModelAttribute;

1, @PathVariable 

When a @RequestMapping URI template style mapping is used, that is, someUrl/{paramId}, paramId can then be bound to the method parameters via the @Pathvariable annotation.

2, @RequestHeader,@CookieValue

@ The RequestHeader annotation binds the value of the Request request header part to the method parameters.

3,@RequestParam, @RequestBody

@RequestParam 

A) Typically used to handle simple type bindings, String obtained by request.getParameter() can be directly converted to simple type cases (String - > simple type conversion operations are performed by ConversionService configured converters); because parameters are obtained by request.getParameter(), the value of queryString in get mode can be processed, and the post side can also be processed. The value of body data in the formula;

B) Used to process Content-Type: content encoded for application/x-www-form-urlencoded, submitted by GET, POST;

C) The annotation has two attributes: value, required; value is used to specify the id name of the value to be passed in, and required is used to indicate whether the parameter must be bound;

@RequestBody

This annotation is often used to deal with Content-Type: content that is not encoded by application/x-www-form-urlencoded, such as application/json, application/xml, etc.

It parses the post data body by using the HTTP Message Converters configured by the Handler Adapter and binds it to the corresponding bean.

Because of the configuration of FormHttpMessageConverter, it can also be used to process the content of application/x-www-form-urlencoded. The processed results are placed in a MultiValueMap < String, String > which is used in some special needs. See the FormHttpMessageConverter api for details.

4,@SessionAttributes, @ModelAttribute

@SessionAttributes:

This annotation is used to bind the value of the attribute s object in HttpSession for easy use in the parameters of the method.

The annotation has two attributes: value and types, which can specify the attributes object to be used by name and type.

@ModelAttribute

The annotation has two uses, one for methods and the other for parameters.

Used methodologically: A model that needs to be queried from the background for request binding before processing @RequestMapping;

When used on parameters: the value of the corresponding name is bound to the annotated parameter bean by name correspondence; the value to be bound comes from:

A) On the attribute s object enabled by @SessionAttributes;

B) @ModelAttribute is used for the model object specified on the method.

C) In both cases, a new bean object needs to be bound, and then the value in the request is bound to the bean by name.

notes

How are parameters bound without any annotations?

By analyzing the source code of Annotation Method Handler Adapter and Request Mapping Handler Adapter, it is found that the parameters of the method are given without any parameters:

Simple type of object to bind: Call @RequestParam to process.   

Complex type of object to bind: Call @ModelAttribute to process.

The simple type here refers to Java Conversion Service, such as Boolean, Int, etc., can convert String directly into the type of target object.

 

hanler's processing code logic is as follows

 

private Object[] resolveHandlerArguments(Method handlerMethod, Object handler,  
            NativeWebRequest webRequest, ExtendedModelMap implicitModel) throws Exception {  
  
        Class[] paramTypes = handlerMethod.getParameterTypes();  
        Object[] args = new Object[paramTypes.length];  
  
        for (int i = 0; i < args.length; i++) {  
            MethodParameter methodParam = new MethodParameter(handlerMethod, i);  
            methodParam.initParameterNameDiscovery(this.parameterNameDiscoverer);  
            GenericTypeResolver.resolveParameterType(methodParam, handler.getClass());  
            String paramName = null;  
            String headerName = null;  
            boolean requestBodyFound = false;  
            String cookieName = null;  
            String pathVarName = null;  
            String attrName = null;  
            boolean required = false;  
            String defaultValue = null;  
            boolean validate = false;  
            Object[] validationHints = null;  
            int annotationsFound = 0;  
            Annotation[] paramAnns = methodParam.getParameterAnnotations();  
  
            for (Annotation paramAnn : paramAnns) {  
                if (RequestParam.class.isInstance(paramAnn)) {  
                    RequestParam requestParam = (RequestParam) paramAnn;  
                    paramName = requestParam.value();  
                    required = requestParam.required();  
                    defaultValue = parseDefaultValueAttribute(requestParam.defaultValue());  
                    annotationsFound++;  
                }  
                else if (RequestHeader.class.isInstance(paramAnn)) {  
                    RequestHeader requestHeader = (RequestHeader) paramAnn;  
                    headerName = requestHeader.value();  
                    required = requestHeader.required();  
                    defaultValue = parseDefaultValueAttribute(requestHeader.defaultValue());  
                    annotationsFound++;  
                }  
                else if (RequestBody.class.isInstance(paramAnn)) {  
                    requestBodyFound = true;  
                    annotationsFound++;  
                }  
                else if (CookieValue.class.isInstance(paramAnn)) {  
                    CookieValue cookieValue = (CookieValue) paramAnn;  
                    cookieName = cookieValue.value();  
                    required = cookieValue.required();  
                    defaultValue = parseDefaultValueAttribute(cookieValue.defaultValue());  
                    annotationsFound++;  
                }  
                else if (PathVariable.class.isInstance(paramAnn)) {  
                    PathVariable pathVar = (PathVariable) paramAnn;  
                    pathVarName = pathVar.value();  
                    annotationsFound++;  
                }  
                else if (ModelAttribute.class.isInstance(paramAnn)) {  
                    ModelAttribute attr = (ModelAttribute) paramAnn;  
                    attrName = attr.value();  
                    annotationsFound++;  
                }  
                else if (Value.class.isInstance(paramAnn)) {  
                    defaultValue = ((Value) paramAnn).value();  
                }  
                else if (paramAnn.annotationType().getSimpleName().startsWith("Valid")) {  
                    validate = true;  
                    Object value = AnnotationUtils.getValue(paramAnn);  
                    validationHints = (value instanceof Object[] ? (Object[]) value : new Object[] {value});  
                }  
            }  
  
            if (annotationsFound > 1) {  
                throw new IllegalStateException("Handler parameter annotations are exclusive choices - " +  
                        "do not specify more than one such annotation on the same parameter: " + handlerMethod);  
            }  
  
            if (annotationsFound == 0) {// If no annotations are found  
                Object argValue = resolveCommonArgument(methodParam, webRequest);    //Determine whether WebRquest can be assigned to parameters  
                if (argValue != WebArgumentResolver.UNRESOLVED) {  
                    args[i] = argValue;  
                }  
                else if (defaultValue != null) {  
                    args[i] = resolveDefaultValue(defaultValue);  
                }  
                else {  
                    Class<?> paramType = methodParam.getParameterType();  
                    if (Model.class.isAssignableFrom(paramType) || Map.class.isAssignableFrom(paramType)) {  
                        if (!paramType.isAssignableFrom(implicitModel.getClass())) {  
                            throw new IllegalStateException("Argument [" + paramType.getSimpleName() + "] is of type " +  
                                    "Model or Map but is not assignable from the actual model. You may need to switch " +  
                                    "newer MVC infrastructure classes to use this argument.");  
                        }  
                        args[i] = implicitModel;  
                    }  
                    else if (SessionStatus.class.isAssignableFrom(paramType)) {  
                        args[i] = this.sessionStatus;  
                    }  
                    else if (HttpEntity.class.isAssignableFrom(paramType)) {  
                        args[i] = resolveHttpEntityRequest(methodParam, webRequest);  
                    }  
                    else if (Errors.class.isAssignableFrom(paramType)) {  
                        throw new IllegalStateException("Errors/BindingResult argument declared " +  
                                "without preceding model attribute. Check your handler method signature!");  
                    }  
                    else if (BeanUtils.isSimpleProperty(paramType)) {// Determine whether the parameter type is a simple type, if it is handled in @RequestParam mode or @ModelAttribute mode?  
                        paramName = "";  
                    }  
                    else {  
                        attrName = "";  
                    }  
                }  
            }  
  
            if (paramName != null) {  
                args[i] = resolveRequestParam(paramName, required, defaultValue, methodParam, webRequest, handler);  
            }  
            else if (headerName != null) {  
                args[i] = resolveRequestHeader(headerName, required, defaultValue, methodParam, webRequest, handler);  
            }  
            else if (requestBodyFound) {  
                args[i] = resolveRequestBody(methodParam, webRequest, handler);  
            }  
            else if (cookieName != null) {  
                args[i] = resolveCookieValue(cookieName, required, defaultValue, methodParam, webRequest, handler);  
            }  
            else if (pathVarName != null) {  
                args[i] = resolvePathVariable(pathVarName, methodParam, webRequest, handler);  
            }  
            else if (attrName != null) {  
                WebDataBinder binder =  
                        resolveModelAttribute(attrName, methodParam, implicitModel, webRequest, handler);  
                boolean assignBindingResult = (args.length > i + 1 && Errors.class.isAssignableFrom(paramTypes[i + 1]));  
                if (binder.getTarget() != null) {  
                    doBind(binder, webRequest, validate, validationHints, !assignBindingResult);  
                }  
                args[i] = binder.getTarget();  
                if (assignBindingResult) {  
                    args[i + 1] = binder.getBindingResult();  
                    i++;  
                }  
                implicitModel.putAll(binder.getBindingResult().getModel());  
            }  
        }  
  
        return args;  
    }  

 

 

Original address

http://blog.csdn.net/walkerjong/article/details/7946109

http://blog.csdn.net/walkerjong/article/details/7994326

Keywords: Attribute JSON xml Java

Added by skope on Tue, 25 Jun 2019 00:38:51 +0300