自定义解密注解

在开发中,有时候会遇到前端body加密,后端解密操作,接下来用注解实现

1、新增DecodeRequestBodyAdvice类

package com.xx.advice;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;

@ControllerAdvice(basePackages = "com.xx.controller")
@Slf4j
public class DecodeRequestBodyAdvice implements RequestBodyAdvice {
    @Override
    public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        return true;
    }

    @Override
    public Object handleEmptyBody(Object body, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        return body;
    }

    @Override
    public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) throws IOException {
        try {
            boolean encode = false;
            if (methodParameter.getMethod().isAnnotationPresent(AesDecrypt.class)) {
                //获取注解配置的包含和去除字段
                AesDecrypt serializedField = methodParameter.getMethodAnnotation(AesDecrypt.class);
                //入参是否需要解密
                encode = serializedField.inDecode();
            }
            if (encode) {
                log.info("对方法method :【" + methodParameter.getMethod().getName() + "】返回数据进行解密");
                return new MyHttpInputMessage(inputMessage);
            } else {
                return inputMessage;
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("对方法method :【" + methodParameter.getMethod().getName() + "】返回数据进行解密出现异常:" + e.getMessage());
            return inputMessage;
        }
    }

    @Override
    public Object afterBodyRead(Object body, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        return body;
    }


    class MyHttpInputMessage implements HttpInputMessage {
        private HttpHeaders headers;
        private InputStream body;

        public MyHttpInputMessage(HttpInputMessage httpInputMessage) throws Exception {
            this.headers = httpInputMessage.getHeaders();
            String requestData = IOUtils.toString(httpInputMessage.getBody(), "utf-8");
            System.out.println("--encryptStr:" + requestData);
            String encryptStr = easpString(requestData).replace("\"", "");
            String decrypt = AESUtil.decrypt(encryptStr);
            this.body = IOUtils.toInputStream(decrypt, "utf-8");
        }

        @Override
        public InputStream getBody() throws IOException {
            return body;
        }

        @Override
        public HttpHeaders getHeaders() {
            return headers;
        }

        public String easpString(String requestData) {
            if (requestData != null && !requestData.equals("")) {
                String s = "{\"encryptStr\":";
                //去除requestData中的转义字符
                String data = requestData.replaceAll("\\s*|\r|\n|\t", "");
                if (!data.startsWith(s)) {
                    throw new RuntimeException("参数【encryptStr】缺失异常!");
                } else {
                    int closeLen = data.length() - 1;
                    int openLen = "{\"encryptStr\":".length();
                    String substring = StringUtils.substring(data, openLen, closeLen);
                    return substring;
                }
            }
            return "";
        }

    }
}

2、新增AesDecrypt

package com.xx.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface AesDecrypt {

    //入参是否解密,默认解密
    boolean inDecode() default true;
    //出参是否加密,默认加密
    boolean outEncode() default true;

}

注意:AESUtil可以直接网上copy一份,和前端一一对应加密秘钥

3、使用

@PostMapping("/addUser")
    @AesDecrypt
    public ResponseBean<String> addUser(@RequestBody UserLoginRequest loginRequest) {
        ResponseBean<String> responseBean = new ResponseBean<>();
        sysUserService.addUser(loginRequest);
        responseBean.setSuccess(true);
        responseBean.setMessage("新增用户成功");
        return responseBean;
  }

即可解密

4、前端请求body

{"encryptStr":"加密body"}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值