spring注解@ResponseBody

来源:互联网 发布:mac pro 15寸 携带 编辑:程序博客网 时间:2024/05/04 17:14

今天工作的时候,一不小心就对spring如何通过注解来解析请求好奇了。
查询了资料,spring mvc请求处理大致是这样子的,由DispatcherServlet截获请求,DispatcherServlet通过handlerMappng得到HandlerExecutionChain。然后获得HandlerAdapter。
HandlerAdapter内部对于每个请求生成一个ServletInvocableHandlerMethod进行处理。而ServletInvocableHandlerMethod处理时会分成请求和响应两部分进行。然后ServletInvocableHandlerMethod得到ModelAndView进行处理。
1. 处理请求的时候,会根据ServletInvocableHandlerMethod的属性argumentResolvers(这个属性是它的父类InvocableHandlerMethod中定义的)进行处理,其中argumentResolvers属性是一个HandlerMethodArgumentResolverComposite类(这里使用了组合模式的一种变形),这个类是实现了HandlerMethodArgumentResolver接口的类,里面有各种实现了HandlerMethodArgumentResolver的List集合。

  1. 处理响应的时候,会根据ServletInvocableHandlerMethod的属性returnValueHandlers(自身属性)进行处理,returnValueHandlers属性是一个HandlerMethodReturnValueHandlerComposite类(这里使用了组合模式的一种变形),这个类是实现了HandlerMethodReturnValueHandler接口的类,里面有各种实现了HandlerMethodReturnValueHandler的List集合。

ServletInvocableHandlerMethod的returnValueHandlers和argumentResolvers这两个属性都是在ServletInvocableHandlerMethod进行实例化的时候被赋值的(使用RequestMappingHandlerAdapter的属性进行赋值)。

RequestMappingHandlerAdapter的argumentResolvers和returnValueHandlers这两个属性是在RequestMappingHandlerAdapter进行实例化的时候被Spring容器注入的。
其中默认的ArgumentResolvers:

默认的returnValueHandlers:

使用@ResponseBody注解的话最终返回值会被RequestResponseBodyMethodProcessor这个HandlerMethodReturnValueHandler实现类处理。

我们通过源码发现,RequestResponseBodyMethodProcessor这个类其实同时实现了HandlerMethodReturnValueHandler和HandlerMethodArgumentResolver这两个接口。

RequestResponseBodyMethodProcessor支持的请求类型是Controller方法参数中带有@RequestBody注解,支持的响应类型是Controller方法带有@ResponseBody注解。

RequestResponseBodyMethodProcessor响应的具体处理是使用消息转换器。

处理请求的时候使用内部的readWithMessageConverters方法。

然后会执行父类(AbstractMessageConverterMethodArgumentResolver)的readWithMessageConverters方法。

“`java
protected Object readWithMessageConverters(NativeWebRequest webRequest,
MethodParameter methodParam, Type paramType) throws IOException, HttpMediaTypeNotSupportedException {

    final HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);    HttpInputMessage inputMessage = new ServletServerHttpRequest(servletRequest);    InputStream inputStream = inputMessage.getBody();    if (inputStream == null) {        return handleEmptyBody(methodParam);    }    else if (inputStream.markSupported()) {        inputStream.mark(1);        if (inputStream.read() == -1) {            return handleEmptyBody(methodParam);        }        inputStream.reset();    }    else {        final PushbackInputStream pushbackInputStream = new PushbackInputStream(inputStream);        int b = pushbackInputStream.read();        //如果返回的值是空的        if (b == -1) {            //检查有没有Responsebody注解,有抛出一个异常            return handleEmptyBody(methodParam);        }        else {            pushbackInputStream.unread(b);        }        inputMessage = new ServletServerHttpRequest(servletRequest) {            @Override            public InputStream getBody() throws IOException {                // Form POST should not get here                return pushbackInputStream;            }        };    }

//有数据,则调用父类的方法
return super.readWithMessageConverters(inputMessage, methodParam, paramType);
}

父类的方法readWithMessageConverters,通过对应的media的类型调用HttpMessageConverter方法,遍历并且使用了Read方法。
java
protected Object readWithMessageConverters(HttpInputMessage inputMessage,
MethodParameter methodParam, Type targetType) throws IOException, HttpMediaTypeNotSupportedException {

    MediaType contentType;    try {        contentType = inputMessage.getHeaders().getContentType();    }    catch (InvalidMediaTypeException ex) {        throw new HttpMediaTypeNotSupportedException(ex.getMessage());    }    if (contentType == null) {        contentType = MediaType.APPLICATION_OCTET_STREAM;    }    Class<?> contextClass = methodParam.getContainingClass();    for (HttpMessageConverter<?> converter : this.messageConverters) {        if (converter instanceof GenericHttpMessageConverter) {            GenericHttpMessageConverter<?> genericConverter = (GenericHttpMessageConverter<?>) converter;            if (genericConverter.canRead(targetType, contextClass, contentType)) {                if (logger.isDebugEnabled()) {                    logger.debug("Reading [" + targetType + "] as \"" +                            contentType + "\" using [" + converter + "]");                }                return genericConverter.read(targetType, contextClass, inputMessage);            }        }        Class<T> targetClass = (Class<T>)                ResolvableType.forMethodParameter(methodParam, targetType).resolve(Object.class);        if (converter.canRead(targetClass, contentType)) {            if (logger.isDebugEnabled()) {                logger.debug("Reading [" + targetClass.getName() + "] as \"" +                        contentType + "\" using [" + converter + "]");            }            return ((HttpMessageConverter<T>) converter).read(targetClass, inputMessage);        }    }    throw new HttpMediaTypeNotSupportedException(contentType, this.allSupportedMediaTypes);}

“`

0 0
原创粉丝点击