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"
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM