springMVC源码分析--HttpMessageConverter参数read操作(二)

上一篇博客 springMVC源码分析--HttpMessageConverter数据转化(一)中我们简单介绍了一下HttpMessageConverter接口提供的几个方法,主要有以下几个方法:

(1)canRead 是否可以读

(2)canWrite 是否可以写

(3)read() 读数据

(4)write() 写数据

接下来我们介绍一下读取数据的处理操作。

首先要去重温一下参数处理器需要做的操作springMVC源码分析--RequestParamMethodArgumentResolver参数解析器(三),AbstractNamedValueMethodArgumentResolver中的resolveArgument方法,解析参数值


public final Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
            NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        .......
        Object arg = resolveName(namedValueInfo.name, parameter, webRequest);
        ......
    }
简单的提交数据的示例:


 @RequestMapping(value="/save")
    public String saveProduct( String name,@RequestBody String description,@RequestBody float price, Model model)
   .......
}
我们可以在HandlerMethodArgumentResolver的子类RequestResponseBodyMethodProcessor的方法resolveArgument看到如下处理,这里就是对提交的参数的处理

public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
            NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
 
        Object arg = readWithMessageConverters(webRequest, parameter, parameter.getGenericParameterType());
        .........
    }
接下来在readWithMessageConverters中的处理如下:

@Override
    protected <T> Object readWithMessageConverters(NativeWebRequest webRequest, MethodParameter methodParam,
            Type paramType) throws IOException, HttpMediaTypeNotSupportedException, HttpMessageNotReadableException {
        HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
        ServletServerHttpRequest inputMessage = new ServletServerHttpRequest(servletRequest);
        Object arg = readWithMessageConverters(inputMessage, methodParam, paramType);
        if (arg == null) {
            if (methodParam.getParameterAnnotation(RequestBody.class).required()) {
                throw new HttpMessageNotReadableException("Required request body is missing: " +
                        methodParam.getMethod().toGenericString());
            }
        }
        return arg;
    }
在父类AbstractMessageConverterMethodArgumentResolver的方法readWithMessageConverters中的处理如下:简单来说就是根据提供的实现的HttpMessageConverter来对提交的RequestBody中的数据进行转换处理。
@SuppressWarnings("unchecked")
    protected <T> Object readWithMessageConverters(HttpInputMessage inputMessage, MethodParameter param,
            Type targetType) throws IOException, HttpMediaTypeNotSupportedException, HttpMessageNotReadableException {
        //获取数据类型
        MediaType contentType;
        boolean noContentType = false;
        try {
            contentType = inputMessage.getHeaders().getContentType();
        }
        catch (InvalidMediaTypeException ex) {
            throw new HttpMediaTypeNotSupportedException(ex.getMessage());
        }
        if (contentType == null) {
            noContentType = true;
            contentType = MediaType.APPLICATION_OCTET_STREAM;
        }
 
        Class<?> contextClass = (param != null ? param.getContainingClass() : null);
        Class<T> targetClass = (targetType instanceof Class<?> ? (Class<T>) targetType : null);
        if (targetClass == null) {
            ResolvableType resolvableType = (param != null ?
                    ResolvableType.forMethodParameter(param) : ResolvableType.forType(targetType));
            targetClass = (Class<T>) resolvableType.resolve();
        }
 
        HttpMethod httpMethod = ((HttpRequest) inputMessage).getMethod();
        Object body = NO_VALUE;
 
        try {
            inputMessage = new EmptyBodyCheckingHttpInputMessage(inputMessage);
            //选择适合的消息处理器来处理参数
            for (HttpMessageConverter<?> converter : this.messageConverters) {
                Class<HttpMessageConverter<?>> converterType = (Class<HttpMessageConverter<?>>) converter.getClass();
                //判断是否适合处理参数
                if (converter instanceof GenericHttpMessageConverter) {
                    GenericHttpMessageConverter<?> genericConverter = (GenericHttpMessageConverter<?>) converter;
                    if (genericConverter.canRead(targetType, contextClass, contentType)) {
                        if (logger.isDebugEnabled()) {
                            logger.debug("Read [" + targetType + "] as \"" + contentType + "\" with [" + converter + "]");
                        }
                        if (inputMessage.getBody() != null) {
                            inputMessage = getAdvice().beforeBodyRead(inputMessage, param, targetType, converterType);
                            //处理参数
                            body = genericConverter.read(targetType, contextClass, inputMessage);
                            body = getAdvice().afterBodyRead(body, inputMessage, param, targetType, converterType);
                        }
                        else {
                            body = null;
                            body = getAdvice().handleEmptyBody(body, inputMessage, param, targetType, converterType);
                        }
                        break;
                    }
                }
                else if (targetClass != null) {
                    if (converter.canRead(targetClass, contentType)) {
                        if (logger.isDebugEnabled()) {
                            logger.debug("Read [" + targetType + "] as \"" + contentType + "\" with [" + converter + "]");
                        }
                        if (inputMessage.getBody() != null) {
                            inputMessage = getAdvice().beforeBodyRead(inputMessage, param, targetType, converterType);
                            //处理数据,对于简单的String数据使用StringHttpMessageConverter进行处理
                            body = ((HttpMessageConverter<T>) converter).read(targetClass, inputMessage);
                            body = getAdvice().afterBodyRead(body, inputMessage, param, targetType, converterType);
                        }
                        else {
                            body = null;
                            body = getAdvice().handleEmptyBody(body, inputMessage, param, targetType, converterType);
                        }
                        break;
                    }
                }
            }
        }
        catch (IOException ex) {
            throw new HttpMessageNotReadableException("Could not read document: " + ex.getMessage(), ex);
        }
 
        if (body == NO_VALUE) {
            if (httpMethod == null || !SUPPORTED_METHODS.contains(httpMethod) ||
                    (noContentType && inputMessage.getBody() == null)) {
                return null;
            }
            throw new HttpMediaTypeNotSupportedException(contentType, this.allSupportedMediaTypes);
        }
        //最终返回处理的结果值
        return body;
    }
springMVC默认提供了很多参数和结果值处理器,包括如下:

(1)MappingJackson2HttpMessageConverter

(2)GsonHttpMessageConverter

(3)ByteArrayHttpMessageConverter

(4)ObjectToStringHttpMessageConverter

(5)ProtobufHttpMessageConverter

(6)ResourceHttpMessageConverter

(7)StringHttpMessageConverter

(8)AllEncompassingFormHttpMessageConverter
--------------------- 
作者:归田 
来源:CSDN 
原文:https://blog.csdn.net/qq924862077/article/details/55271569 
版权声明:本文为博主原创文章,转载请附上博文链接!

转载于:https://my.oschina.net/u/1999167/blog/3011666

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值