编写自定义的Spring MVC消息转化器

来源:互联网 发布:android wear源码下载 编辑:程序博客网 时间:2024/05/29 18:05

场景:大多数时候Spring MVC自带的消息转化器已经满足需要了,为了学习此处还是编写一下自定义的消息转化器

原理:消息转化器的原理如下图


编码

1.编写自定义的消息转化器

public class CustomJsonHttpMessageConverter implements HttpMessageConverter {    private ObjectMapper mapper=new ObjectMapper();    private List supportedMediaTypes= Arrays.asList(MediaType.APPLICATION_JSON);    /**     * 判断转换器是否可以将输入内容转换成Java     * @param aClass     * @param mediaType     * @return     */    @Override    public boolean canRead(Class aClass, MediaType mediaType) {        if(mediaType==null){            return false;        }        for(MediaType supportedMediaType : getSupportedMediaTypes()){            if(supportedMediaType.includes(mediaType)){                return true;            }        }        return false;    }    /**     * 判断转换器能否将Java类型转换成指定的输出内容     * @param aClass     * @param mediaType     * @return     */    @Override    public boolean canWrite(Class aClass, MediaType mediaType) {        if(mediaType==null || MediaType.ALL.equals(mediaType)){            return true;        }        for(MediaType supportedMediaType:getSupportedMediaTypes()){            if(supportedMediaType.includes(mediaType)){                return true;            }        }        return false;    }    @Override    public List<MediaType> getSupportedMediaTypes() {        return supportedMediaTypes;    }    /**     * 读取请求内容将其中的Json转换为Java对象     * @param aClass             需要转化的Java类型     * @param httpInputMessage   请求对象     * @return     * @throws IOException     * @throws HttpMessageNotReadableException     */    @Override    public Object read(Class aClass, HttpInputMessage httpInputMessage) throws IOException, HttpMessageNotReadableException {        return mapper.readValue(httpInputMessage.getBody(),aClass);    }    /**     * 将Java对象转化成Json返回内容     * @param o                     需要转化的对象     * @param mediaType             返回类型     * @param httpOutputMessage     回执对象     * @throws IOException     * @throws HttpMessageNotWritableException     */    @Override    public void write(Object o, MediaType mediaType, HttpOutputMessage httpOutputMessage) throws IOException, HttpMessageNotWritableException {        OutputStream outputStream=httpOutputMessage.getBody();        outputStream.write("hello world".getBytes());        mapper.writeValue(outputStream,o);    }}
2.将消息转化器注册到Spring MVC中

@Configurationpublic class WebMvcConfig extends WebMvcConfigurerAdapter {    @Override    public void addInterceptors(InterceptorRegistry registry) {        /**         * 如果这里拦截全部 即 /** 的话,就会导致拦截器的方法被执行两次,原因还不明确         */        registry.addInterceptor(httpTest()).addPathPatterns("/h1/h3"+"/**");        super.addInterceptors(registry);    }    @Override    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {        converters.add(new CustomJsonHttpMessageConverter());        super.configureMessageConverters(converters);    }}
3.编写测试代码

@RequestMapping(value = "h3")    public @ResponseBody Object testHeader(@RequestBody String haha) {        System.out.println("controller里面="+haha);        Pet pet=new Pet();        pet.setName("hello");        return pet;    }

标注了@RequestBody注解的Controller方法在获取到数据后,将会根据content-type 的类型找到合适的消息转化器,而被@ResponseBody标注的方法在返回数据的时候,同样的也会根据content-Type寻找合适的消息转换器转化为的相应的数据返回,上面的例子中使用了APPLICATION_JSON,同时也可以自定义Content-Type 为这种特定的content-Type编写相应的消息转换器。