做网站要求电脑配置,wordpress做h5,物流网站的建设论文,广州微信网站建设前文通过阅读源码#xff0c;深入分析了DispatcherServlet及相关组件的工作流程#xff0c;本文不再阅读源码#xff0c;介绍一下扩展HttpMessageConverter的方式。
HttpMessageConverter工作方式及扩展方式
前文介绍过#xff0c;HttpMessageConverter是读写请求体和响应…前文通过阅读源码深入分析了DispatcherServlet及相关组件的工作流程本文不再阅读源码介绍一下扩展HttpMessageConverter的方式。
HttpMessageConverter工作方式及扩展方式
前文介绍过HttpMessageConverter是读写请求体和响应体的组件。
RequestResponseBodyMethodProcessor(用于解析请求参数、处理返回值)从内置的HttpMessageConverter查找支持当前请求体、响应体的实例然后调用read、write来读写数据。
Spring内置的HttpMessageConverter在装配RequestResponseBodyMethodProcessor的时候创建具体代码在WebMvcConfigurationSupport类addDefaultHttpMessageConverters方法中。
开发者如果要扩展使用自己的HttpMessageConverter实现可以编写组件实现WebMvcConfigurer接口在extendMessageConverters方法中注入自己的HttpMessageConverter实现类对象。
自定义HttpMessageConverter
需求描述
系统需要对响应体进行加密、对请求体解密操作。
思路
编写类实现HttpMessageConverter接口read方法中先对请求体解密之后在做json反序列化write方法先做json序列化之后再加密通过WebMvcConfigurer注册
编写HttpMessageConverter实现类
public class MyMappingJackson2HttpMessageConverter implements GenericHttpMessageConverterObject {private static final String S_KEY 1234567890123456;private static final String IV_PARAMETER abcdefghijklmnop;// 用来做json序列化和反序列化自己编写代码也可以此处直接使用MappingJackson2HttpMessageConverter来做private final MappingJackson2HttpMessageConverter jackson2HttpMessageConverter;// 读写字符串private final StringHttpMessageConverter stringHttpMessageConverter;public MyMappingJackson2HttpMessageConverter(MappingJackson2HttpMessageConverter jackson2HttpMessageConverter) {this.jackson2HttpMessageConverter jackson2HttpMessageConverter;this.stringHttpMessageConverter new StringHttpMessageConverter(StandardCharsets.UTF_8);}Overridepublic boolean canRead(Class? clazz, MediaType mediaType) {return jackson2HttpMessageConverter.canRead(clazz, mediaType);}Overridepublic boolean canWrite(Class? clazz, MediaType mediaType) {return jackson2HttpMessageConverter.canWrite(clazz, mediaType);}Overridepublic ListMediaType getSupportedMediaTypes() {return jackson2HttpMessageConverter.getSupportedMediaTypes();}Overridepublic Object read(Class? clazz, HttpInputMessage inputMessage)throws IOException, HttpMessageNotReadableException {// 读取请求原始字节byte[] bytes readBytes(inputMessage);// 解密byte[] decryptBytes AesUtil.decrypt(bytes, S_KEY, IV_PARAMETER);// 封装HttpInputMessage供下面反序列化使用HttpInputMessage in new MyHttpInputMessage(inputMessage, decryptBytes);// json反序列化return jackson2HttpMessageConverter.read(clazz, in);}Overridepublic void write(Object o, MediaType contentType, HttpOutputMessage outputMessage)throws IOException, HttpMessageNotWritableException {ByteArrayOutputStream byteArrayOutputStream new ByteArrayOutputStream();// json序列化jackson2HttpMessageConverter.write(o, contentType, new MyHttpOutputMessage(outputMessage, byteArrayOutputStream));byte[] bytes byteArrayOutputStream.toByteArray();// 加密byte[] encryptStr AesUtil.encrypt(bytes, S_KEY, IV_PARAMETER);// 将响应写出去this.stringHttpMessageConverter.write(new String(encryptStr, StandardCharsets.UTF_8), contentType, outputMessage);}Overridepublic boolean canRead(Type type, Class? contextClass, MediaType mediaType) {return jackson2HttpMessageConverter.canRead(type, contextClass, mediaType);}Overridepublic Object read(Type type, Class? contextClass, HttpInputMessage inputMessage)throws IOException, HttpMessageNotReadableException {byte[] bytes readBytes(inputMessage);byte[] decryptBytes AesUtil.decrypt(bytes, S_KEY, IV_PARAMETER);HttpInputMessage in new MyHttpInputMessage(inputMessage, decryptBytes);return jackson2HttpMessageConverter.read(type, contextClass, in);}Overridepublic boolean canWrite(Type type, Class? clazz, MediaType mediaType) {return jackson2HttpMessageConverter.canWrite(type, clazz, mediaType);}Overridepublic void write(Object o, Type type, MediaType contentType, HttpOutputMessage outputMessage)throws IOException, HttpMessageNotWritableException {ByteArrayOutputStream byteArrayOutputStream new ByteArrayOutputStream();jackson2HttpMessageConverter.write(o, type, contentType, new MyHttpOutputMessage(outputMessage, byteArrayOutputStream));byte[] bytes byteArrayOutputStream.toByteArray();byte[] encryptStr AesUtil.encrypt(bytes, S_KEY, IV_PARAMETER);this.stringHttpMessageConverter.write(new String(encryptStr, StandardCharsets.UTF_8), contentType, outputMessage);}private byte[] readBytes(HttpInputMessage inputMessage) throws IOException {long contentLength inputMessage.getHeaders().getContentLength();ByteArrayOutputStream bos new ByteArrayOutputStream(contentLength 0 ? (int) contentLength : StreamUtils.BUFFER_SIZE);StreamUtils.copy(inputMessage.getBody(), bos);return bos.toByteArray();}private static class MyHttpInputMessage implements HttpInputMessage {private final HttpInputMessage originalHttpInputMessage;private final byte[] buf;public MyHttpInputMessage(HttpInputMessage originalHttpInputMessage, byte[] buf) {this.originalHttpInputMessage originalHttpInputMessage;this.buf buf;}Overridepublic InputStream getBody() throws IOException {return new ByteArrayInputStream(this.buf);}Overridepublic HttpHeaders getHeaders() {HttpHeaders headers this.originalHttpInputMessage.getHeaders();headers.setContentLength(this.buf.length);return headers;}}private static class MyHttpOutputMessage implements HttpOutputMessage {private final HttpOutputMessage originalHttpOutputMessage;private final OutputStream outputStream;public MyHttpOutputMessage(HttpOutputMessage originalHttpOutputMessage,OutputStream outputStream) {this.originalHttpOutputMessage originalHttpOutputMessage;this.outputStream outputStream;}Overridepublic OutputStream getBody() throws IOException {return this.outputStream;}Overridepublic HttpHeaders getHeaders() {return this.originalHttpOutputMessage.getHeaders();}}
}注入HttpMessageConverter实现类对象
Component
public class MyWebMvcConfigurer implements WebMvcConfigurer {Overridepublic void extendMessageConverters(ListHttpMessageConverter? converters) {MappingJackson2HttpMessageConverter converter null;for (HttpMessageConverter? messageConverter : converters) {if (messageConverter instanceof MappingJackson2HttpMessageConverter) {converter (MappingJackson2HttpMessageConverter) messageConverter;break;}}if (converter ! null) {// 注入MyMappingJackson2HttpMessageConverterMyMappingJackson2HttpMessageConverter myMappingJackson2HttpMessageConverter new MyMappingJackson2HttpMessageConverter(converter);converters.add(0, myMappingJackson2HttpMessageConverter);}}
}