SpringMVC 学习笔记(七) JSON返回:HttpMessageConverter作用

时间:2021-08-13 18:02:38

1.1. 返回JSON

POM.XML:

<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.1.4</version>
		</dependency>

在方法上面添加@ResponseBody注解

SpringMVC 学习笔记(七) JSON返回:HttpMessageConverter作用

1.2. HttpMessageConverter

HttpMessageConverter<T> 是 Spring3.0 新添加的一个接口,负责将请求信息转换为一个对象(类型为 T),将对象(类型为 T)输出为响应信息

public interface HttpMessageConverter<T> {

	/**
	 * 指定转换器可以读取的对象类型,
     * 即转换器是否可将请求信息转换为 clazz 类型的对象,
     * 同时指定支持 MIME 类型(text/html,applaiction/json等)
	 */
	boolean canRead(Class<?> clazz, MediaType mediaType);

	/**
	 * 指定转换器是否可将 clazz 类型的对象写到响应流中,
     * 响应流支持的媒体类型
     * 在MediaType 中定义。
	 */
	boolean canWrite(Class<?> clazz, MediaType mediaType);

	/**
	 * 该转换器支持的媒体类型。	 
     */
	List<MediaType> getSupportedMediaTypes();

	/**
	 * 将请求信息流转换为 T 类型的对象。
	 */
	T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
			throws IOException, HttpMessageNotReadableException;

	/**
	 * 将T类型的对象写到响应流中,同时指定相应的媒体类型为 contentType
	 */
	void write(T t, MediaType contentType, HttpOutputMessage outputMessage)
			throws IOException, HttpMessageNotWritableException;

}

1.2.1. HttpMessageConverter<T> 的实现类

SpringMVC 学习笔记(七) JSON返回:HttpMessageConverter作用

1.2.2. 处理流程

SpringMVC 学习笔记(七) JSON返回:HttpMessageConverter作用


SpringMVC 学习笔记(七) JSON返回:HttpMessageConverter作用


SpringMVC 学习笔记(七) JSON返回:HttpMessageConverter作用

DispatcherServlet 默认装配RequestMappingHandlerAdapter 

RequestMappingHandlerAdapter 默认装配如下HttpMessageConverter

SpringMVC 学习笔记(七) JSON返回:HttpMessageConverter作用

当加入jsckson 包后,RequestMappingHandlerAdapter装配的 HttpMessageConverter 如下:

SpringMVC 学习笔记(七) JSON返回:HttpMessageConverter作用

使用 HttpMessageConverter<T> 将请求信息转化并绑定到处理方法的入参中或将响应结果转为对应类型的响应信息,Spring 提供了两种途径:

– 使用 @RequestBody / @ResponseBody 对处理方法进行标注

– 使用 HttpEntity<T> / ResponseEntity<T> 作为处理方法的入参或返回值

当控制器处理方法使用到@RequestBody/@ResponseBody

HttpEntity<T>/ResponseEntity<T> , Spring 首先根据请求头或响应头的Accept 属性选择匹配的 HttpMessageConverter进而根据参数类型或泛型类型的过滤得到匹配的 HttpMessageConverter若找不到可用的HttpMessageConverter 将报错

@RequestBody 和 @ResponseBody 不需要成对出现

SpringMVC 学习笔记(七) JSON返回:HttpMessageConverter作用SpringMVC 学习笔记(七) JSON返回:HttpMessageConverter作用SpringMVC 学习笔记(七) JSON返回:HttpMessageConverter作用SpringMVC 学习笔记(七) JSON返回:HttpMessageConverter作用


1.2.3. @RequestBody@ResponseBody示例

	
	@ResponseBody
	@RequestMapping("/responseBody")
	public byte[] responseBody(HttpSession session) throws IOException {
		ServletContext servletContext = session.getServletContext();
		InputStream in = servletContext.getResourceAsStream("/WEB-INF/files/download.txt");
		byte[] fileData = FileCopyUtils.copyToByteArray(in);
		return fileData;
	}
	
	@RequestMapping("/requestBody")
	public String requestBody(@RequestBody String body){
		System.out.println(body);
		return "helloworld";
	}

JSP:

<form action="requestBody" method="POST" enctype="multipart/form-data">
	File: <input type="file" name="file"/>
	Desc: <input type="text" name="desc"/>
	<input type="submit" value="Submit"/>
</form>
<br>
<br>
<a href="responseBody"> responseBody </a>
<br>
<br>

1.2.4. HttpEntityResponseEntity 示例

	@RequestMapping("/httpEntity")
	public String httpEntity(HttpEntity<String> entity){
		System.out.println(entity.getHeaders().getContentLength());
		return "helloworld";
	}
	
	@RequestMapping("/download")
	public ResponseEntity<byte[]> responseEntity(HttpSession session) throws IOException{
		byte [] body = null;
		ServletContext servletContext = session.getServletContext();
		InputStream in = servletContext.getResourceAsStream("/WEB-INF/files/download.txt");
		body = new byte[in.available()];
		in.read(body);
		
		HttpHeaders headers = new HttpHeaders();
		headers.add("Content-Disposition", "attachment;filename=download.txt");
		
		HttpStatus statusCode = HttpStatus.OK;
		
		ResponseEntity<byte[]> response = new ResponseEntity<byte[]>(body, headers, statusCode);
		return response;
	}
JSP:
<br>
<a href="download"> download </a>
<br>
<br>
<a href="httpEntity"> httpEntity </a>
<br>
<br>