zoukankan      html  css  js  c++  java
  • 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就会使用它。

  • 相关阅读:
    几种常见的基于Lucene的开源搜索解决方案对比
    【例子】Bobobrowse:lucene分组统计扩展组件
    Solr 相似页面MoreLikeThis
    eclipse安装、基本使用、常用设置
    iPhone开发入门守则:ObjectiveC编码规范系列教程
    ios开发学习按钮(Button)效果源码分享
    ios开发学习音频声效(Audio)效果源码分享系列教程
    ios开发学习动画(Animation)效果源码分享系列教程1
    ios开发学习图表(Chart)效果源码分享系列教程
    局网满猿关不住,一波码农出墙来。
  • 原文地址:https://www.cnblogs.com/weiyinfu/p/6861074.html
Copyright © 2011-2022 走看看