摘要:大部分人的第一反应是通过 Spring 拦截器(Interceptor)中的postHandler方法处理。实际这是行不通的,因为当程序运行到该方法,是在返回数据之后,渲染页面之前,所以这时候 Response 中的输出流已经关闭了,自然无法在对返回数据进行处理。
其实这个问题用几行代码就可以搞定,因为 Spring 提供了非常丰富的扩展支持,无论是之前提到的Interceptor和MethodArgumentResolver,还是接下来要提到的HttpMessageConverter。
这里你要明白一个原理:在 Spring MVC 的 Controller 层经常会用到@RequestBody和@ResponseBody,通过这两个注解,可以在 Controller 中直接使用 Java 对象作为请求参数和返回内容,而完成这之间转换作用的便是HttpMessageConverter。
HttpMessageConverter接口提供了 5 个方法:
1. canRead:判断该转换器是否能将请求内容转换成 Java 对象
2. canWrite:判断该转换器是否可以将 Java 对象转换成返回内容
3. getSupportedMediaTypes:获得该转换器支持的 MediaType 类型
4. read:读取请求内容并转换成 Java 对象
5. write:将 Java 对象转换后写入返回内容
其中read和write方法的参数分别有有HttpInputMessage和HttpOutputMessage对象,这两个对象分别代表着一次 Http 通讯中的请求和响应部分,可以通过getBody方法获得对应的输入流和输出流。
具体步骤:这里使用的springBoot的方法进行配置
首先继承 MappingJackson2HttpMessageConverter 并重写 writeInternal 和 read 方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
|
@Component public class MyMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {
Logger logger = LoggerFactory.getLogger(getClass());
@Override public Object read(Type type, @Nullable Class<?> contextClass, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException { JavaType javaType = this.getJavaType(type, contextClass);
InputStream is = inputMessage.getBody();
ByteArrayOutputStream out = new ByteArrayOutputStream(); byte[] b = new byte[4096]; int n = 0; while ((n = is.read(b)) > 0) { out.write(b, 0, n); } String plainBody = out.toString(); logger.info("现在的参数是:"+plainBody); String newParams = RSAUtils.decryptDataOnJava(plainBody, RsaConstant.privateKey);
try { return this.objectMapper.readValue(new ByteArrayInputStream(newParams.getBytes()), javaType); } catch (IOException ex) { throw new HttpMessageNotReadableException("Could not read document: " + ex.getMessage(), ex); } }
@Override protected void writeInternal(Object object, @Nullable Type type, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException { String json = objectMapper.writeValueAsString (object); logger.info ("原来的json"+json); String result = json ; logger.info ("加密后的json"+result); outputMessage.getBody().write(result.getBytes()); }
}
|
然后实现WebMvcConfigurer,需要将这个自定义的转换器配置到 Spring 中,这里通过重写WebMvcConfigurer中的configureMessageConverters方法添加自定义转换器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
@Configuration public class WebConfigurer implements WebMvcConfigurer {
@Resource private MyMappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter;
Logger logger = LoggerFactory.getLogger(getClass());
@Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { converters.add (mappingJackson2HttpMessageConverter); }
}
|
到这里大致的步骤已经做完,中间需要你加上你的加密解密的工具。其他的使用就和你平常还是一样。但是这里是全局加密也就是说所有的接口都被加密或者解密