SpringMvc返回JSON的工作原理。

您所在的位置:网站首页 responsemapping SpringMvc返回JSON的工作原理。

SpringMvc返回JSON的工作原理。

2023-11-12 05:52| 来源: 网络整理| 查看: 265

一:导入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 readability 13 * @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} otherwise 16 */ 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 writability 22 * @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} otherwise 25 */ 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 types 31 */ 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 the 37 * {@link #canRead canRead} method of this interface, which must have returned {@code true}. 38 * @param inputMessage the HTTP input message to read from 39 * @return the converted object 40 * @throws IOException in case of I/O errors 41 * @throws HttpMessageNotReadableException in case of conversion errors 42 */ 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 \"" + contentType 23 +"\" 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); }

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3