知方号

知方号

SpringMvc返回JSON的工作原理。<返回json对象的注解方法>

SpringMvc返回JSON的工作原理。

一:导入jar包。然后在springmvc.xml中配置上这么一句话

1 2

会自动注册DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapter 两个bean,是spring MVC为@Controllers分发请求所必须的。并提供了:数据绑定支持,@NumberFormatannotation支持,@DateTimeFormat支持,@Valid支持,读写XML的支持(JAXB),读写JSON的支持(Jackson)。

二:在方法中前面加上这么一个注解:

@ResponseBodyreturn返回的就是一个JSON的对象。而不是去跳转到页面上。原理:使用HtppMessageConverter这个类。这个类负责将请求信息转换成一个对象。将对象输出为响应信息。

简介:@RequestBody

作用: 

      i) 该注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上;

      ii) 再把HttpMessageConverter返回的对象数据绑定到 controller中方法的参数上。

使用时机:

A) GET、POST方式提时, 根据request header Content-Type的值来判断:

    application/x-www-form-urlencoded, 可选(即非必须,因为这种情况的数据@RequestParam, @ModelAttribute也可以处理,当然@RequestBody也能处理);    multipart/form-data, 不能处理(即使用@RequestBody不能处理这种格式的数据);    其他格式, 必须(其他格式包括application/json, application/xml等。这些格式的数据,必须使用@RequestBody来处理);

 

B) PUT方式提交时, 根据request header Content-Type的值来判断:

 

    application/x-www-form-urlencoded, 必须;    multipart/form-data, 不能处理;    其他格式, 必须;

说明:request的body部分的数据编码格式由header部分的Content-Type指定;

 

 

@ResponseBody

 

作用: 

      该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。

使用时机:

      返回的数据不是html标签的页面,而是其他某种格式的数据时(如json、xml等)使用;

1 /** 2 * Strategy interface that specifies a converter that can convert from and to HTTP requests and responses. 3 * 4 * @author Arjen Poutsma 5 * @author Juergen Hoeller 6 * @since 3.0 7 */ 8 public interface HttpMessageConverter { 9 10 /**11 * Indicates whether the given class can be read by this converter.12 * @param clazz the class to test for readability13 * @param mediaType the media type to read, can be {@code null} if not specified.14 * Typically the value of a {@code Content-Type} header.15 * @return {@code true} if readable; {@code false} otherwise16 */17 boolean canRead(Class clazz, MediaType mediaType);18 19 /**20 * Indicates whether the given class can be written by this converter.21 * @param clazz the class to test for writability22 * @param mediaType the media type to write, can be {@code null} if not specified.23 * Typically the value of an {@code Accept} header.24 * @return {@code true} if writable; {@code false} otherwise25 */26 boolean canWrite(Class clazz, MediaType mediaType);27 28 /**29 * Return the list of {@link MediaType} objects supported by this converter.30 * @return the list of supported media types31 */32 List getSupportedMediaTypes();33 34 /**35 * Read an object of the given type form the given input message, and returns it.36 * @param clazz the type of object to return. This type must have previously been passed to the37 * {@link #canRead canRead} method of this interface, which must have returned {@code true}.38 * @param inputMessage the HTTP input message to read from39 * @return the converted object40 * @throws IOException in case of I/O errors41 * @throws HttpMessageNotReadableException in case of conversion errors42 */43 T read(Class messageConverter : this.messageConverters) {19 allSupportedMediaTypes.addAll(messageConverter.getSupportedMediaTypes());20 if (messageConverter.canRead(paramType, contentType)) {21 if (logger.isDebugEnabled()) {22 logger.debug("Reading [" + paramType.getName() + "] as "" + contentType23 +"" using [" + messageConverter + "]");24 }25 return messageConverter.read(paramType, inputMessage);26 }27 }28 }29 throw new HttpMediaTypeNotSupportedException(contentType, allSupportedMediaTypes);30 }

@ResponseBody注解时: 根据Request对象header部分的Accept属性(逗号分隔),逐一按accept中的类型,去遍历找到能处理的HttpMessageConverter;

源代码如下:

private void writeWithMessageConverters(Object returnValue, HttpInputMessage inputMessage, HttpOutputMessage outputMessage) throws IOException, HttpMediaTypeNotAcceptableException { List acceptedMediaTypes = inputMessage.getHeaders().getAccept(); if (acceptedMediaTypes.isEmpty()) { acceptedMediaTypes = Collections.singletonList(MediaType.ALL); } MediaType.sortByQualityValue(acceptedMediaTypes); Class returnValueType = returnValue.getClass(); List allSupportedMediaTypes = new ArrayList(); if (getMessageConverters() != null) { for (MediaType acceptedMediaType : acceptedMediaTypes) { for (HttpMessageConverter messageConverter : getMessageConverters()) { if (messageConverter.canWrite(returnValueType, acceptedMediaType)) { messageConverter.write(returnValue, acceptedMediaType, outputMessage); if (logger.isDebugEnabled()) { MediaType contentType = outputMessage.getHeaders().getContentType(); if (contentType == null) { contentType = acceptedMediaType; } logger.debug("Written [" + returnValue + "] as "" + contentType + "" using [" + messageConverter + "]"); } this.responseArgumentUsed = true; return; } } } for (HttpMessageConverter messageConverter : messageConverters) { allSupportedMediaTypes.addAll(messageConverter.getSupportedMediaTypes()); } } throw new HttpMediaTypeNotAcceptableException(allSupportedMediaTypes); }

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至lizi9903@foxmail.com举报,一经查实,本站将立刻删除。