Spring 接口数据加密—局部加密
- 注解
- RequestBody 解密
- ResponseBody 加密
- 使用
注解
package com.base.project.commcon.annotation.des;
import java.lang.annotation.*;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DecryptRequestBody {
boolean dencrypt() default true;
}
-
DecryptRequestBody注解
- 自定义解密注解,默认设置解密==true, 注解适用于方法上
package com.base.project.commcon.annotation.des;
import java.lang.annotation.*;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EncryptResponBody {
boolean encrypt() default true;
}
-
EncryptResponBody
- 自定义解密注解
RequestBody 解密
package com.base.project.advice;
import com.base.project.commcon.annotation.des.DecryptRequestBody;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.GsonHttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
/**
* 这里只针对application/json的数据进行请求解密
*/
@ControllerAdvice
public class AppRequestBodyAdvice implements RequestBodyAdvice {
@Override
public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
if(GsonHttpMessageConverter.class.isAssignableFrom(aClass)){
return true;
}
return false;
}
@Override
public Object handleEmptyBody(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
return o;
}
@Override
public HttpInputMessage beforeBodyRead(HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) throws IOException {
boolean dencrypt = false;
HttpInputMessage returnInputMessage = null;
if(methodParameter.getMethod().isAnnotationPresent(DecryptRequestBody.class)) {
DecryptRequestBody body = methodParameter.getMethodAnnotation(DecryptRequestBody.class);
dencrypt = body.dencrypt();
}
if(dencrypt) {
InputStream is = httpInputMessage.getBody();
//在此处对数据进行解密
returnInputMessage = new DecryptHttpInputMessage(httpInputMessage.getHeaders(), this.toDencrypt(is));
//returnInputMessage =
}else {
returnInputMessage = httpInputMessage;
}
return returnInputMessage;
}
@Override
public Object afterBodyRead(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
return o;
}
public InputStream toDencrypt(InputStream is) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] b = new byte[4096];
int n = 0;
while ((n = is.read(b)) > 0) {
out.write(b, 0, n);
}
byte[] buf = out.toByteArray();
//对buf进行解密
//
ByteArrayInputStream bis = new ByteArrayInputStream(buf);
return bis;
}
class DecryptHttpInputMessage implements HttpInputMessage{
private HttpHeaders headers = null;
private InputStream is = null;
public DecryptHttpInputMessage(HttpHeaders headers, InputStream is) {
this.headers = headers;
this.is = is;
}
@Override
public HttpHeaders getHeaders() {
// TODO Auto-generated method stub
return headers;
}
@Override
public InputStream getBody() throws IOException {
// TODO Auto-generated method stub
return is;
}
}
}
ResponseBody 加密
package com.base.project.advice;
import com.base.project.commcon.annotation.des.EncryptResponBody;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.GsonHttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import java.io.IOException;
/**
* 这里只针对application/json的数据进行响应加密
*/
@ControllerAdvice
public class AppResponseBodyAdvice implements ResponseBodyAdvice {
@Override
public boolean supports(MethodParameter methodParameter, Class aClass) {
if(GsonHttpMessageConverter.class.isAssignableFrom(aClass)){
return true;
}
return false;
}
@Override
public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
boolean encrypt = false;
if(methodParameter.getMethod().isAnnotationPresent(EncryptResponBody.class)) {
EncryptResponBody encryptBody = methodParameter.getMethodAnnotation(EncryptResponBody.class);
encrypt = encryptBody.encrypt();
}
if(encrypt) {
try {
//对数据进行加密返回
byte[] buf = this.toEncrypt(o);
serverHttpResponse.getBody().write(buf);
return null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return o;
}
private byte[] toEncrypt(Object o){
//object内容进行加密
return o.toString().getBytes();
}
}
使用
将注解设置在要解密或者解密,或者加解密的action方法上即可。