关于Spring MVC中@ResponseBody怎么知道我需要什么类型


@ResponseBody注解在 method上具体返回什么类型的数据流(json、xml等)主要有两个方面决定的:1. 是否有对应的第三方jar包出现在classpath,比如jackson jar、jaxb2
jar,如果只存在spring mvc就会注册对应的HttpMessageConvert(将return
obj写为response的流是靠httpMessageConvert的实现类来完成的) 2.
有@RequestMapping注解的consumes具体的mediaTypes和http请求的accept能结束的mime
type来联合决定。
有这两点决定@ResponseBody注解的返回值的返回流的类型具体的实现参见
RequestResponseBodyMthodProcessor,java中,具体的写流实现如下在
AbstractMessageConverterMethodProcessor.writeWithMessageConverters()来实现
的。具体代码:

/** 
     * Writes the given return type to the given output message. 
     * 
     * @param returnValue the value to write to 轿州the output message 
     * @param returnType the type of the value 
     * @param inputMessage the input messages. Used to inspect the {@code Accept} header. 
     * @param outputMessage the output message to write to 
     * 皮老@throws IOException thrown in case of I/O errors 
     * @throws HttpMediaTypeNotAcceptableException thrown when the conditions indicated by {@code Accept} header on 
     * the request cannot be met by the message converters 
     */  
    @SuppressWarnings("unchecked")  
    protected <T> void writeWithMessageConverters(T returnValue,  
                                           燃帆升     MethodParameter returnType,  
                                                ServletServerHttpRequest inputMessage,  
                                                ServletServerHttpResponse outputMessage)  
            throws IOException, HttpMediaTypeNotAcceptableException {  
  
        Class<?> returnValueClass = returnValue.getClass();  
  
        HttpServletRequest servletRequest = inputMessage.getServletRequest();  
        List<MediaType> requestedMediaTypes = getAcceptableMediaTypes(servletRequest);  
        List<MediaType> producibleMediaTypes = getProducibleMediaTypes(servletRequest, returnValueClass);  
  
        Set<MediaType> compatibleMediaTypes = new LinkedHashSet<MediaType>();  
        for (MediaType r : requestedMediaTypes) {  
            for (MediaType p : producibleMediaTypes) {  
                if (r.isCompatibleWith(p)) {  
                    compatibleMediaTypes.add(getMostSpecificMediaType(r, p));  
                }  
            }  
        }  
        if (compatibleMediaTypes.isEmpty()) {  
            throw new HttpMediaTypeNotAcceptableException(producibleMediaTypes);  
        }  
  
        List<MediaType> mediaTypes = new ArrayList<MediaType>(compatibleMediaTypes);  
        MediaType.sortBySpecificityAndQuality(mediaTypes);  
  
        MediaType selectedMediaType = null;  
        for (MediaType mediaType : mediaTypes) {  
            if (mediaType.isConcrete()) {  
                selectedMediaType = mediaType;  
                break;  
            }  
            else if (mediaType.equals(MediaType.ALL) || mediaType.equals(MEDIA_TYPE_APPLICATION)) {  
                selectedMediaType = MediaType.APPLICATION_OCTET_STREAM;  
                break;  
            }  
        }  
  
        if (selectedMediaType != null) {  
            selectedMediaType = selectedMediaType.removeQualityValue();  
            for (HttpMessageConverter<?> messageConverter : messageConverters) {  
                if (messageConverter.canWrite(returnValueClass, selectedMediaType)) {  
                    ((HttpMessageConverter<T>) messageConverter).write(returnValue, selectedMediaType, outputMessage);  
                    if (logger.isDebugEnabled()) {  
                        logger.debug("Written [" + returnValue + "] as \"" + selectedMediaType + "\" using [" +  
                                messageConverter + "]");  
                    }  
                    return;  
                }  
            }  
        }  
        throw new HttpMediaTypeNotAcceptableException(allSupportedMediaTypes);  
    }