SpringBoot对Json返回值加密处理

对返回给前端的敏感字段进行加密

比如手机号码,身份证号码等。

实现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

声明:本博客文章为原创,只代表本人在工作学习中某一时间内总结的观点或结论。转载时请在文章页面明显位置给出原文链接。

猜你喜欢

转载自www.cnblogs.com/se7end/p/11325266.html