在日常写项目中经常一般正规的项目都需要将信息加密后返回前端,前端进行解密后再展示出来给用户,这样做的目的无一不是为了安全,在Java开发中,如何简单快速的完成这个功能呢,这里就需要用到这两个接口ResponseBodyAdvice和RequestBodyAdvice。
ResponseBodyAdvice是 spring 4.1 新加入的一个接口,在消息体被HttpMessageConverter写入之前允许Controller 中 @ResponseBody修饰的方法调整响应中的内容,比如进行相应的加密或者进行统一处理返回值/响应体。【同样RequestBodyAdvice也是在 sping 新加入的一个接口,它可以使用在 @RequestBody 或 HttpEntity 修饰的参数读取之前进行参数的处理,比如进行参数的解密】 通俗来讲就是在数据返回前端之前可以通过这个ResponseBodyAdvice接口来将响应中的数据进行操作后再返回前端。接下来直接上代码
1.首先需要自己写一个类来实现ResponseBodyAdvice这个接口,然后重写方法
2.supports这个方法返回参数是布尔值,返回false则代表不走到beforeBodyWrite这个方法,返回true则代表走到这个方法。因此可以在这里进行检查方法是否有我们自己定义的注解,比如我的代码就是检查了方法参数上有没有EncryptBody这个注解,有的话就会去进行beforeBodyWrite方法的执行。
3.beforeBodyWrite这个方法中的参数body就是你返回前端的所有body,在这里可以判断参数类型,并对参数进行加密操作。
java
@Component
@ControllerAdvice
public class EncryptBodyAdvice implements ResponseBodyAdvice {
@Override
public boolean supports(MethodParameter returnType, Class converterType) {
return returnType.hasMethodAnnotation(EncryptBody.class);
}
@Autowired
private ObjectMapper objectMapper;
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
if (body instanceof AjaxResult) {
//AjaxResult类型加密
AjaxResult ajaxResult =(AjaxResult) body;
ajaxResult.put("encrypt",true);
Object bodyData = ajaxResult.get("data");
ajaxResult.put("data",handleENCData(bodyData));
return ajaxResult;
} else if (body instanceof TableDataInfo) {
//TableDataInfo类型加密
TableDataInfo tableDataInfo =(TableDataInfo) body;
tableDataInfo.setEncrypt(true);
if (!CollectionUtils.isEmpty(tableDataInfo.getRows())){
tableDataInfo.setRows(handleENCData(tableDataInfo.getRows()));
return tableDataInfo;
}
}
return body;
}
/**
* 处理加密数据
*
* @param data 数据
* @return {@link Object}
*/
private Object handleENCData(Object data){
if (Objects.isNull(data)){
return data;
}
//自动关流
try {
return Base64.encode(objectMapper.writeValueAsString(data));
}catch (Exception e){
e.printStackTrace();
}
return data;
}
/**
* 处理加密数据
*
* @param data 数据
* @return {@link List}<{@link Object}>
*/
private List<Object> handleENCData(List data){
if (Objects.isNull(data)){
return data;
}
try {
List<Object> newData = new ArrayList<>();
for (Object datum : data) {
//base64加密
newData.add(Base64.encode(objectMapper.writeValueAsString(datum)));
}
return newData;
}catch (Exception e){
e.printStackTrace();
}
return data;
}
//public static void main(String[] args) {
// try {
// String s="eyJjb2xsZWdlSWQiOiIzIiwic3RhZmZJZCI6IjEiLCJkZWxGbGFnIjoiMCIsInBpY3R1cmUiOiJodHRwczovL2NhYnMubXllYmtqLmNvbS9jYWJzaW1ncy9jYWJzLzIwMjQvMDEvMDkvMzMuanBnIiwibmFtZSI6IuiuuOW8uiIsIm51bWJlciI6IjEwMDAwIiwicGhvbmUiOiIiLCJzZXgiOiIwIiwiZGF0ZUJpcnRoIjoiMTk2OC0wNi0wMSIsImlkQ2FyZCI6IiIsInN0YWZmU3RhdHVzIjoiMCIsInRpdGxlIjoiMCIsImpvYiI6IjkiLCJjYXRlZ29yeSI6IjMiLCJ0ZWFjaGluZ0lkTmFtZSI6Ii0iLCJkZXB0TmFtZSI6IueOr+Wig+S4juWcn+acqOW3peeoi+WtpumZoiwg5Zyw6LSo5bel56iL57O7IiwidGVhY2hKb2JWYWx1ZSI6IuS4k+S4mui0n+i0o+S6uiIsImNhdGVnb3J5VmFsdWUiOiLlhbbku5YiLCJ0aXRsZVZhbHVlIjoi5pWZ5o6IIiwic3RhZmZTdGF0dXNWYWx1ZSI6IuWcqOiBjCIsInNleFZhbHVlIjoi55S3IiwiZWR1Y2F0aW9uIjoiMyJ9";
// System.out.println(new String(Base64.decode(s)));
// //System.out.println(Base64.encode("123456"));
// } catch (Exception e){
//
// }
//}
}
同理RequestBodyAdvice操作也类似,这里不再举例
java
@Component
@ControllerAdvice
public class DecryptBodyAdvice implements RequestBodyAdvice {
@Override
public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
return false;
}
@Override
public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException {
return null;
}
@Override
public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
return null;
}
@Override
public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
return null;
}
}