SpringMVC消息转换器HttpMessageConverter

Http数据转换的原理

在这里插入图片描述
当一个HTTP请求到达时是一个InputStream,通过HttpMessageConverter转换为java对象,从而进行参数接收。
当对一个HTTP请求进行响应时,我们首先输出的是一个java对象,然后由HttpMessageConverter转换为OutputStream输出。

当我们在Spring Boot应用中集成了jackson的类库之后,如下的一些HttpMessageConverter将会被加载:

实现类功能说明
StringHttpMessageConverter将请求信息转为字符串
FormHttpMessageConverter将表单数据读取到MultiValueMap中
XmlAwareFormHttpMessageConverter扩展与FormHttpMessageConverter,如果部分表单属性是XML数据,可用该转换器进行读取
ResourceHttpMessageConverter读写org.springframework.core.io.Resource对象
BufferedImageHttpMessageConverter读写BufferedImage对象
ByteArrayHttpMessageConverter读写二进制数据
SourceHttpMessageConverter读写java.xml.transform.Source类型的对象
MarshallingHttpMessageConverter通过Spring的org.springframework,xml.Marshaller和Unmarshaller读写XML消息
Jaxb2RootElementHttpMessageConverter通过JAXB2读写XML消息,将请求消息转换为标注的XmlRootElement和XmlType连接的类中
MappingJacksonHttpMessageConverter利用Jackson开源包的ObjectMapper读写JSON数据
RssChannelHttpMessageConverter读写RSS种子消息
AtomFeedHttpMessageConverter和RssChannelHttpMessageConverter能够读写RSS种子消息

根据HTTP协议的Accept和Content-Type属性,以及参数数据类型来判别使用哪一种HttpMessageConverter。当使用RequestBody或ResponseBody时,再结合前端发送的Accept数据类型,会自动判定优先使用MappingJacksonHttpMessageConverter作为数据转换器。

不仅JSON可以表达对象数据类型,XML也可以。如果我们希望使用XML格式该怎么告知Spring呢,那就要使用到produces属性了。

@GetMapping(value ="/demo",produces = MediaType.APPLICATION_XML_VALUE)

这里我们明确的告知了返回的数据类型是xml,就会使用Jaxb2RootElementHttpMessageConverter作为默认的数据转换器。当然实现XML数据响应比JSON还会更复杂一些,还需要结合@XmlRootElement、@XmlElement等注解实体类来使用。

自定义HttpMessageConverter

其实绝大多数的数据格式都不需要我们自定义HttpMessageConverter,都有第三方类库可以帮助我们实现(包括下文代码中的Excel格式)。但有的时候,有些数据的输出格式并没有类似于Jackson这种类库帮助我们处理,需要我们自定义数据格式。

步骤:

  1. 实现AbstractHttpMessageConverter接口
  2. 指定该转换器是针对哪种数据格式的?如上文代码中的"application/vnd.ms-excel"
  3. 指定该转换器针对那些对象数据类型?如上文代码中的supports函数
  4. 使用writeInternal对数据进行输出处理,上例中是输出为Excel格式。
@Service
public class TeamToXlsConverter extends AbstractHttpMessageConverter<Team> {
    private static final MediaType EXCEL_TYPE = MediaType.valueOf("application/vnd.ms-excel");
    TeamToXlsConverter() {
        super(EXCEL_TYPE);
    }
    @Override
    protected Team readInternal(final Class<? extends Team> clazz, final HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
        return null;
    }
    @Override
    protected boolean supports(final Class<?> clazz) {
        return (Team.class == clazz);
    }
    @Override
    protected void writeInternal(final Team team, final HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
        try (final Workbook workbook = new HSSFWorkbook()) {
            final Sheet sheet = workbook.createSheet();
            int rowNo = 0;
            for (final TeamMember member : team.getMembers()) {
                final Row row = sheet.createRow(rowNo++);
                row.createCell(0)
                   .setCellValue(member.getName());
            }
            workbook.write(outputMessage.getBody());
        }
    }
}

上面代码只是帮助我们理解的一个例子,不要用于生产。

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梁云亮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值