对返回给前端的敏感字段进行加密
比如手机号码,身份证号码等。
实现org.springframework.web.method.support.HandlerMethodReturnValueHandler接口
实现类:ResultWarpReturnValueHandler
public class ResultWarpReturnValueHandler implements HandlerMethodReturnValueHandler {
private final HandlerMethodReturnValueHandler delegate;
public ResultWarpReturnValueHandler(HandlerMethodReturnValueHandler delegate) {
this.delegate = delegate;
}
@Override
public boolean supportsReturnType(MethodParameter returnType) {
return delegate.supportsReturnType(returnType);
}
@Override
public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
delegate.handleReturnValue(convertReturnValue(returnType), returnType, mavContainer, webRequest);
}
private Object convertReturnValue(Object source) {
if (null != source) {
jsonEncrypt(source);
}
return source;
}
private void jsonEncrypt(Object source) {
if(source instanceof List) {
Iterable iterable = (Iterable) source;
for (Object object : iterable) {
doJsonEncrypt(object);
}
} else if(source instanceof Result) {
Result<?> result = (Result<?>) source;
if(null != result.getData()) {
doJsonEncrypt(result.getData());
}
} else {
doJsonEncrypt(source);
}
}
private void doJsonEncrypt(Object object) {
Field[] fields = object.getClass().getDeclaredFields();
if(ArrayUtils.isNotEmpty(fields)) {
for (Field field : fields) {
JsonEncrypt jsonEncrypt = field.getAnnotation(JsonEncrypt.class);
if(null != jsonEncrypt) {
doJsonEncrypt(field, jsonEncrypt, object);
}
}
}
}
private void doJsonEncrypt(Field field, JsonEncrypt jsonEncrypt, Object object) {
try {
field.setAccessible(true);
Object val = field.get(object);
if(null != val) {
// 加密值
String strVal = String.valueOf(val);
// 加密参数
String spanChar = jsonEncrypt.value();
int beginIdx = jsonEncrypt.beginIdx(), endIdx = jsonEncrypt.endIdx();
// 设置加密后的值
field.set(object, EncryptViewUtils.toEncryptView(strVal, spanChar, beginIdx, endIdx));
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
配置:ReturnValueConfig
@Configuration
public class ReturnValueConfig implements InitializingBean {
@Autowired
private RequestMappingHandlerAdapter requestMappingHandlerAdapter;
@Override
public void afterPropertiesSet() throws Exception {
List<HandlerMethodReturnValueHandler> unmodifiableList = requestMappingHandlerAdapter.getReturnValueHandlers();
List<HandlerMethodReturnValueHandler> list = new ArrayList<>(unmodifiableList.size());
for (HandlerMethodReturnValueHandler returnValueHandler : unmodifiableList) {
if (returnValueHandler instanceof RequestResponseBodyMethodProcessor) {
list.add(new ResultWarpReturnValueHandler(returnValueHandler));
} else {
list.add(returnValueHandler);
}
}
requestMappingHandlerAdapter.setReturnValueHandlers(list);
}
}
在类 ResultWarpReturnValueHandler 中的 handleReturnValue 方法里面,参数 returnValue 就是返回的对象。
业务注解:
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface JsonEncrypt {
public String value() default "*";
public int beginIdx() default 0;
public int endIdx() default 0;
}
User类:
// 身份证号码
@JsonEncrypt(beginIdx = 4, endIdx = 13)
private String idCard;
加密处理类:
public class EncryptViewUtils {
/**
* 字符串加密
*
* @param strVal 字符串
* @param spanChar 加密字符
* @param beginIdx 开始下标
* @param endIdx 结束下标
* @return 加密后的字符串
*/
public static String toEncryptView(String strVal, String spanChar, int beginIdx, int endIdx) {
// 不为空
if (StringUtils.isNotEmpty(strVal)) {
// 修正开始下标位移问题
if (beginIdx < 0) {
beginIdx = 0;
}
// 修正结束下标位移问题
if (endIdx > strVal.length()) {
endIdx = strVal.length() - 1;
}
// 处理结束下标小于开始下标的问题
if(beginIdx > endIdx) {
endIdx = beginIdx;
}
StringBuilder builder = new StringBuilder();
// 如果结束下标是0
if (endIdx == 0) {
builder.append(spanChar);
} else {
// 循环处理加密字符
char[] chars = strVal.toCharArray();
for (int i = 0; i < chars.length; i++) {
if (i >= beginIdx && i <= endIdx) {
builder.append(spanChar);
} else {
builder.append(chars[i]);
}
}
}
return builder.toString();
}
return strVal;
}
}
身份证号码在前端显示
{
"idCard": "1308**********1729"
}
作者:Se7end
声明:本博客文章为原创,只代表本人在工作学习中某一时间内总结的观点或结论。转载时请在文章页面明显位置给出原文链接。