描述
特殊项目中很多数据都较为敏感,为了保证数据的完整性,会在传输过程中使用数据加密。例如(RSA算法、SM2国密算法)来实现数据的安全性。为了简化加解密的操作,自定义实现统一对加解密的处理。
入参解密
使用@RestControllerAdvice(annotations = RestController.class)注解,并且继承RequestBodyAdviceAdapter抽象类,重写里面的supports方法和beforeBodyRead方法。
@RestControllerAdvice注解中的annotations字段表示拦截controller类上存在@RestController注解的类,也可以进行自定义注解实现,或者不填,表示拦截所有的请求。
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdviceAdapter;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
/**
* 接口入参解密
*
* @author 苦瓜不苦
* @date 2022/10/25 0:07
**/
@Slf4j
@RestControllerAdvice(annotations = RestController.class)
public class DecryptConfig extends RequestBodyAdviceAdapter {
/**
* 该方法用于判断当前请求,是否要执行beforeBodyRead方法
*
* @param methodParameter
* @param type
* @param aClass
* @return
*/
@Override
public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
return true;
}
@Override
public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException {
// 转换为JSON字符串
String body = StreamUtils.copyToString(inputMessage.getBody(), Charset.defaultCharset());
// 解密逻辑处理...
return new HttpInputMessage() {
@Override
public InputStream getBody() throws IOException {
return new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8));
}
@Override
public HttpHeaders getHeaders() {
return inputMessage.getHeaders();
}
};
}
}
出参加密
使用@RestControllerAdvice(annotations = RestController.class)注解,并且继承ResponseBodyAdvice<Object>抽象类,重写里面的supports方法和beforeBodyWrite方法。
@RestControllerAdvice注解中的annotations字段表示拦截controller类上存在@RestController注解的类,也可以进行自定义注解实现,或者不填,表示拦截所有的请求。
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import java.util.Objects;
/**
* 接口出参加密
*
* @author 苦瓜不苦
* @date 2022/10/25 0:16
**/
@Slf4j
@RestControllerAdvice(annotations = RestController.class)
public class EncryptConfig implements ResponseBodyAdvice<Object> {
/**
* 该方法用于判断当前请求的返回值,是否要执行beforeBodyWrite方法
*
* @param methodParameter
* @param aClass
* @return
*/
@Override
public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
return true;
}
@Override
public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
if (Objects.isNull(o)) {
return null;
}
// 转换为JSON字符串
String body = JSONObject.toJSONStringWithDateFormat(o, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat);
// 加密逻辑处理...
return body;
}
}