您当前的位置: 首页 >  http

梁云亮

暂无认证

  • 3浏览

    0关注

    1211博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

SpringMVC消息转换器HttpMessageConverter

梁云亮 发布时间:2020-05-24 15:25:53 ,浏览量:3

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 {
    private static final MediaType EXCEL_TYPE = MediaType.valueOf("application/vnd.ms-excel");
    TeamToXlsConverter() {
        super(EXCEL_TYPE);
    }
    @Override
    protected Team readInternal(final Class 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());
        }
    }
}

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

关注
打赏
1665409997
查看更多评论
立即登录/注册

微信扫码登录

0.3020s