对返回给前端的敏感字段进行加密
比如手机号码,身份证号码等。
实现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" }