spring boot学习(7)— 自定义中的 HttpMessageConverter

在我们开发自己的应用时,有时候,我们可能需要自定义一些自己的数据格式来传输,这时,自定义的数据传输和类的实例之间进行转化就需要统一起来了, Spring MVC 中的 HttpMessageConverter 就派上用场了。

HttpMessageConverter 的声明:

public interface HttpMessageConverter<T> {

    /**
     * Indicates whether the given class can be read by this converter.
     * @param clazz the class to test for readability
     * @param mediaType the media type to read (can be {@code null} if not specified);
     * typically the value of a {@code Content-Type} header.
     * @return {@code true} if readable; {@code false} otherwise
     */
    boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);

    /**
     * Indicates whether the given class can be written by this converter.
     * @param clazz the class to test for writability
     * @param mediaType the media type to write (can be {@code null} if not specified);
     * typically the value of an {@code Accept} header.
     * @return {@code true} if writable; {@code false} otherwise
     */
    boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);

    /**
     * Return the list of {@link MediaType} objects supported by this converter.
     * @return the list of supported media types
     */
    List<MediaType> getSupportedMediaTypes();

    /**
     * Read an object of the given type from the given input message, and returns it.
     * @param clazz the type of object to return. This type must have previously been passed to the
     * {@link #canRead canRead} method of this interface, which must have returned {@code true}.
     * @param inputMessage the HTTP input message to read from
     * @return the converted object
     * @throws IOException in case of I/O errors
     * @throws HttpMessageNotReadableException in case of conversion errors
     */
    T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
            throws IOException, HttpMessageNotReadableException;

    /**
     * Write an given object to the given output message.
     * @param t the object to write to the output message. The type of this object must have previously been
     * passed to the {@link #canWrite canWrite} method of this interface, which must have returned {@code true}.
     * @param contentType the content type to use when writing. May be {@code null} to indicate that the
     * default content type of the converter must be used. If not {@code null}, this media type must have
     * previously been passed to the {@link #canWrite canWrite} method of this interface, which must have
     * returned {@code true}.
     * @param outputMessage the message to write to
     * @throws IOException in case of I/O errors
     * @throws HttpMessageNotWritableException in case of conversion errors
     */
    void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage)
            throws IOException, HttpMessageNotWritableException;

}
复制代码

里面有四个方法:

  1. canRead: 查看对应的类型和 content-type 头部类型是否支持被读取.
  2. canWrite: 查看对应的类型和 content-type 头部类型是否支持输出.
  3. getSupportedMediaTypes: 获取支持的类型
  4. read: 从 http 请求中,读取数据,并转化为指定类型。
  5. write: 将指定类型的实例写入到response中。

内置的常用HttpMessageConverter 类型:

  1. ByteArrayHttpMessageConverter – 转换 byte array 类型数据
  2. StringHttpMessageConverter – 根据编码格式,转化Strings
  3. ResourceHttpMessageConverter – converts org.springframework.core.io.Resource for any type of octet stream
  4. SourceHttpMessageConverter – 转换 javax.xml.transform.Source 类型的数据。
  5. FormHttpMessageConverter – 转换 application/x-www-form-urlencodedmultipart/form-data 类型的消息.
  6. Jaxb2RootElementHttpMessageConverter – 将对象和xml转换。
  7. MappingJackson2HttpMessageConverter – 使用 jackson2 转换 json 数据和 对象实例

自定义 HttpMessageConverter 并使用

  1. 首先,自定义 HttpMessageConverter: 需要转化的对象为:
public class TestRequestInfo {
    private String key;
    private int value;
    private MultipartFile file;

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public MultipartFile getFile() {
        return file;
    }

    @Override
    public String toString() {
        return "TestRequestInfo{" +
                "key='" + key + '\'' +
                ", value=" + value +
                '}';
    }
}
复制代码

Converter

public class TestMessageConverter extends AbstractHttpMessageConverter<TestRequestInfo> {

    public TestMessageConverter(){
        super(new MediaType("application", "test-converter", Charset.forName("UTF-8")));
    }

    @Override
    protected boolean supports(Class<?> clazz) {
        return true;
    }

    @Override
    protected TestRequestInfo readInternal(Class<? extends TestRequestInfo> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
        String temp = StreamUtils.copyToString(inputMessage.getBody(), Charset.forName("UTF-8"));
        TestRequestInfo test = new TestRequestInfo();
        test.setKey(temp);
        return test;
    }

    @Override
    protected void writeInternal(TestRequestInfo testRequestInfo, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
        outputMessage.getBody().write(testRequestInfo.toString().getBytes());
    }
}

复制代码
  1. 注册 HttpMessageConverter:
@EnableWebMvc
@Configuration
@ComponentScan
public class MVCConfig implements WebMvcConfigurer {

    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(new TestMessageConverter());
    }
}
复制代码
  1. 定义 Controller:
@RestController
public class TestController {
    @RequestMapping(
        value="/reports",
        method = {RequestMethod.GET, RequestMethod.POST}
    )
    public @ResponseBody
    TestRequestInfo getReports(@RequestBody TestRequestInfo requestInfo){
        System.out.println(requestInfo);
        return requestInfo;
    }
}
复制代码

请求结果为: {"key":"sdfasfasdf","value":0,"file":null}.

转载于:https://juejin.im/post/5cbc30bee51d456e62545adf

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值