SpringBoot自定义HttpMessageConverter
Spring就是一个大大的插线板,上面插着各种各样的Bean。
SpringBoot大大简化了Spring的配置,将原来放在XML中的配置大量的在代码中使用注解实现。这么做有利有弊,总体上利大于弊。
使用注解的方式在Spring中注册Bean,有四种方式:
- Component
- Service
- Controller,RestController
- Repository
上面这四个注解真是SpringBoot的核心。因为要想使用
@Value属性注入@Resource,@Autowired自动注入
就必须让Spring能够看见使用这些注解的类,也就是说必须在Spring中注册Bean,Spring才会统一帮你管理。
上面“Component”等注解都是用来注解类,注解接口要使用@Bean注解。当让Spring注入接口时,如果接口有多个实例类,需要用@Resource("myUserDaoImpl")这种方式注明实例类的名称;如果接口只有一个实例类,Spring会自动检测合适的类型进行注入。
没有Spring的时候,各个Bean形成的依赖关系是一个错综复杂的图状结构。有了Spring,各个Bean之间松耦合,各个Bean只跟Spring容器有联系,这就形成了总线型的依赖,大大简化了类与类之间的依赖关系。
下面进入正题,我编写了一个Controller,返回User类型的数据,Spring会把User转化成JSON字符串,现在我想对这个字符串进行一些处理再返回。要求不能更改Controller部分的代码,因为我要对全部的返回的JSON都进行这种处理,如果改Controller的话需要更改好多地方。
@RestController
class MyController {
@RequestMapping("user")
User getUser() {
return new User("weidiao", 25);
}
}
虽然这个函数返回的User类型,实际上Spring会把这个对象转换成JSON。跟@ResponseBody、@RequestBody两个注解密切相关的一个接口是:HttpMessageConverter。

消息转换器的目标是:HTTP输入请求格式向Java对象的转换;Java对象向HTTP输出请求的转换。有的消息转换器只支持多个数据类型,有的只支持多个输出格式,还有的两者兼备。
HttpMessageConverter 接口提供了5个方法:
- canRead :判断该转换器是否能将请求内容转换成Java对象
- canWrite :判断该转换器是否可以将Java对象转换成返回内容
- getSupportedMediaTypes :获得该转换器支持的MediaType类型
- read :读取请求内容并转换成Java对象
- write :将Java对象转换后写入返回内容
其中 read 和 write 方法的参数分别有有 HttpInputMessage 和 HttpOutputMessage 对象,这两个对象分别代表着一次Http通讯中的请求和响应部分,可以通过 getBody 方法获得对应的输入流和输出流。
Spring已经默认包含了常用的消息转换器:
| 名称 | 作用 | 读支持MediaType | 写支持MediaType |
|---|---|---|---|
| ByteArrayHttpMessageConverter | 数据与字节数组的相互转换 | / | application/octet-stream |
| StringHttpMessageConverter | 数据与String类型的相互转换 | text/* | text/plain |
| FormHttpMessageConverter | 表单与MultiValueMap<string, string=””>的相互转换 |
application/x-www-form-urlencoded | application/x-www-form-urlencoded |
| SourceHttpMessageConverter | 数据与javax.xml.transform.Source的相互转换 | text/xml和application/xml | text/xml和application/xml |
| MarshallingHttpMessageConverter | 使用Spring的Marshaller/Unmarshaller转换XML数据 | text/xml和application/xml | text/xml和application/xml |
| MappingJackson2HttpMessageConverter | 使用Jackson的ObjectMapper转换Json数据 | application/json | application/json |
| MappingJackson2XmlHttpMessageConverter | 使用Jackson的XmlMapper转换XML数据 | application/xml application/xml | |
| BufferedImageHttpMessageConverter | 数据与java.awt.image.BufferedImage的相互转换 Java I/O API支持的所有类型 | Java I/O API支持的所有类型 |
请看实现
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.List;
@Component
public class MyHttpMessageConverter implements HttpMessageConverter<Object> {
@Override
public boolean canRead(Class<?> aClass, MediaType mediaType) {
return false;
}
@Override
public boolean canWrite(Class<?> aClass, MediaType mediaType) {
return true;
}
@Override
public List<MediaType> getSupportedMediaTypes() {
return Arrays.asList(MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON_UTF8);
}
@Override
public Object read(Class<?> aClass, HttpInputMessage httpInputMessage) throws IOException, HttpMessageNotReadableException {
return null;
}
@Override
public void write(Object o, MediaType mediaType, HttpOutputMessage httpOutputMessage) throws IOException, HttpMessageNotWritableException {
PrintWriter cout = new PrintWriter(httpOutputMessage.getBody());
JSONObject ans = new JSONObject();
ans.put("object", o);
ans.put("successful", o != null);
cout.write(JSON.toJSONString(ans, true));
cout.close();
}
}
使用@Component注解这个类就能够让Spring知道:这里有一个消息转换器。这样Spring就会使用它。
SpringBoot自定义HttpMessageConverter的更多相关文章
- SpringBoot自定义拦截器实现IP白名单功能
SpringBoot自定义拦截器实现IP白名单功能 转载请注明源地址:http://www.cnblogs.com/funnyzpc/p/8993331.html 首先,相关功能已经上线了,且先让我先 ...
- SpringBoot自定义错误信息,SpringBoot适配Ajax请求
SpringBoot自定义错误信息,SpringBoot自定义异常处理类, SpringBoot异常结果处理适配页面及Ajax请求, SpringBoot适配Ajax请求 ============== ...
- SpringBoot自定义错误页面,SpringBoot 404、500错误提示页面
SpringBoot自定义错误页面,SpringBoot 404.500错误提示页面 SpringBoot 4xx.html.5xx.html错误提示页面 ====================== ...
- springboot自定义错误页面
springboot自定义错误页面 1.加入配置: @Bean public EmbeddedServletContainerCustomizer containerCustomizer() { re ...
- SpringBoot自定义Filter
SpringBoot自定义Filter SpringBoot自动添加了OrderedCharacterEncodingFilter和HiddenHttpMethodFilter,当然我们可以自定 义F ...
- springboot 自定义LocaleResolver切换语言
springboot 自定义LocaleResolver切换语言 我们在做项目的时候,往往有很多项目需要根据用户的需要来切换不同的语言,使用国际化就可以轻松解决. 我们可以自定义springboor中 ...
- SpringMVC拦截器与SpringBoot自定义拦截器
首先我们先回顾一下传统拦截器的写法: 第一步创建一个类实现HandlerInterceptor接口,重写接口的方法. 第二步在XML中进行如下配置,就可以实现自定义拦截器了 SpringBoot实现自 ...
- [技术博客] SPRINGBOOT自定义注解
SPRINGBOOT自定义注解 在springboot中,有各种各样的注解,这些注解能够简化我们的配置,提高开发效率.一般来说,springboot提供的注解已经佷丰富了,但如果我们想针对某个特定情景 ...
- 08点睛Spring MVC4.1-Spring MVC的配置(含自定义HttpMessageConverter)
8.1 配置 Spring MVC的配置是通过继承WebMvcConfigurerAdapter类并重载其方法实现的; 前几个教程已做了得配置包括 01点睛Spring MVC 4.1-搭建环境 配置 ...
随机推荐
- coco游戏android.mk
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := game_shared LOCAL_MODULE_FILENAME ...
- [Android UI] ActionBar 自定义属性
actionbar 默认放在顶部, 如果在application或者activity中加入 android:uiOptions="splitActionBarWhenNarrow" ...
- Redis五大数据结构
1.Redis介绍 Redis是REmote DIctionary Server的缩写,作者定位于一个内存KV存储数据库(In-memory key-value Store),让Redis自豪的并不是 ...
- Java文件操作大全
//1.创建文件夹 //import java.io.*; File myFolderPath = new File(str1); try { if (!myFolderPath.exists()) ...
- C/C++ 语言获取文件大小
在C语言中测试文件的大小,主要使用二个标准函数. 1.fseek 函数原型:int fseek ( FILE * stream, long int offset, int origin ); 参数说明 ...
- Spring boot分层和基本概念
后端层次划分: 后端分包: 不同层级之间数据传输:推荐第二种 POJO与JavaBean: POJO就是简单的私有属性,加get/set方法, JavaBean,就是会做一些逻辑处理,包括接收事件,和 ...
- IOS程式语法之block的使用掌握
在现阶IOBlock 是iOS在4.0之后新增的程式语法,严格来说block的概念并不算是基础程式设计的范围,对初学者来说也不是很容易了解,但是在iOS SDK 4.0之后,block几乎出现在所有新 ...
- OpenProcess、GetExitCodeProcess、TerminateProcess
//声明: {返回进程的句柄} OpenProcess( dwDesiredAccess: DWORD; {訪问选项} bInheritHandle: BOOL; {是否能继承; Tr ...
- 【Python学习笔记】
目录 语法 if语句 while循环 字符串常用操作 列表 只读列表元组 字典的使用 语法 if语句 示例 #!/usr/bin/env python user = 'jack' passwd = ' ...
- C#.NET常见问题(FAQ)-浮点数如何四舍五入
使用Math.Round方法即可实现保留指定的小数点后面位数,这种方法返回的还是double类型,而ToString方法并没有做实际转换 更多教学视频和资料下载,欢迎关注以下信息: 我的优酷空间: ...