SpringBoot接口加密解密统一处理(2)

标上注解 ConditionalOnProperty 表示只有条件为true的时候才开启解密功能,一个配置即可打开或者关闭解密功能。真正的解密逻辑留给 DecryptHttpInputMessage , 它又委托给 Crypto。

/** * * @author xiongshiyan */ public class DecryptHttpInputMessage implements HttpInputMessage { private HttpInputMessage inputMessage; private String charset; private Crypto crypto; public DecryptHttpInputMessage(HttpInputMessage inputMessage, String charset , Crypto crypto) { this.inputMessage = inputMessage; this.charset = charset; this.crypto = crypto; } @Override public InputStream getBody() throws IOException { String content = IoUtil.read(inputMessage.getBody() , charset); String decryptBody = crypto.decrypt(content, charset); return new ByteArrayInputStream(decryptBody.getBytes(charset)); } @Override public HttpHeaders getHeaders() { return inputMessage.getHeaders(); } }

对于返回值加密,定义 EncryptResponseBodyAdvice,实现 ResponseBodyAdvice。

/** * 请求响应处理类<br> * * 对加了@Encrypt的方法的数据进行加密操作 * * @author 熊诗言 * */ @ControllerAdvice @ConditionalOnProperty(prefix = "spring.crypto.response.encrypt", name = "enabled" , havingValue = "true", matchIfMissing = true) public class EncryptResponseBodyAdvice implements ResponseBodyAdvice<Object> { @Value("${spring.crypto.request.decrypt.charset:UTF-8}") private String charset = "UTF-8"; @Autowired @Qualifier("rrCrypto") private Crypto crypto; @Override public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) { return true; } @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { boolean encrypt = NeedCrypto.needEncrypt(returnType); if( !encrypt ){ return body; } if(!(body instanceof ResponseMsg)){ return body; } //只针对ResponseMsg的data进行加密 ResponseMsg responseMsg = (ResponseMsg) body; Object data = responseMsg.getData(); if(null == data){ return body; } String xx; Class<?> dataClass = data.getClass(); if(dataClass.isPrimitive() || (data instanceof String)){ xx = String.valueOf(data); }else { //JavaBean、Map、List等先序列化 if(List.class.isAssignableFrom(dataClass)){ xx = JsonUtil.serializeList((List<Object>) data); }else if(Map.class.isAssignableFrom(dataClass)){ xx = JsonUtil.serializeMap((Map<String, Object>) data); }else { xx = JsonUtil.serializeJavaBean(data); } } responseMsg.setData(crypto.encrypt(xx, charset)); return responseMsg; } }

真正的加密逻辑委托给 Crypto ,这是一个加密解密的接口,有很多实现类,参见:链接

/** * Request-Response加解密体系的加解密方式 * @author xiongshiyan at 2018/8/14 , contact me with email yanshixiong@126.com or phone 15208384257 */ @Configuration public class RRCryptoConfig { /** * 加密解密方式使用一样的 */ @Bean("rrCrypto") public Crypto rrCrypto(){ return new AesCrypto("密钥key"); } }

至此,一个完美的对接口的加密解密就实现了。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/065dada508405342bb34d7ac735da99d.html