springboot使用自定义注解进行对实体类参数String类型的base64转换

本文介绍了如何在SpringBoot中利用AOP和自定义注解进行参数处理,特别是对String类型的Base64转换。通过创建一个Base64注解,可以在请求和响应参数中标识需要进行Base64编码或解码的字段。示例代码展示了从控制器到注解再到AOP切面的完整流程,适用于接口参数的其他定制需求。
摘要由CSDN通过智能技术生成

springboot使用自定义注解进行对String的base64转换

说明:使用自定义注解,利用AOP(或filter拦截器)进行对存在注解的实体类参数进行BASE64的字符转换(仅针对String类型)。此方法可以类似地对接口请求和返回参数的其他需求操作。方法不足之处,请多指点,方法仅供参考。

POM (使用到了hutool工具包中的基本类型判断,也可以使用其他的工具包)

        <!--AOP-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
            <version>2.7.1</version>
        </dependency>
        <!--hutool工具类-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-core</artifactId>
            <version>5.8.2</version>
        </dependency>
         <!--LomBok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.2</version>
            <scope>provided</scope>
        </dependency>

controller

 @PostMapping("/base64")
    public BaseResponse<Base64TestRequest> changeToBase64(@RequestBody BaseRequest<Base64TestRequest> request) {
        Base64TestRequest data = request.getData();
        return SuccessReturn.successResponse(
                Base64TestRequest.builder()
                        .original(data.getOriginal())
                        .change(data.getChange())
                        .build()
        );
    }

请求参数pojo

/**
 * @Description: <基本请求格式>
 * @Auther: cly
 * @Date: 2022/03/31/20:03
 **/
@Data
public class BaseRequest<T> {
    private String token;
    @Valid
    private T data;
}
/**
 * @Description: <base64测试实体类>
 * @Auther: cly
 * @Date: 2022/07/09/21:22
 **/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ApiModel("base64测试实体类")
public class Base64TestRequest {
    @ApiModelProperty("原始的字符")
    private String original;
    @ApiModelProperty("base64转换后")
    @Base64
    private String change;
}

返回参数pojo

/**
 * @Description: <基本返回类型>
 * @Auther: cly
 * @Date: 2022/07/03/23:00
 **/
@Data
@NoArgsConstructor
@ApiModel("基本返回类型")
public class BaseResponse<T> {
    private Integer status;
    private T data;
}

自定义参数注解

/**
 * @Description: <BASE64注解>
 * @Auther: cly
 * @Date: 2022/07/03/22:16
 **/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Base64 {
    /**
     * 是否转为BASE64
     * */
    boolean value() default true;
}

AOP拦截进行BASE64转换

/**
 * @Description: <字符内容转为BASE64>
 * @Auther: cly
 * @Date: 2022/07/03/22:06
 **/
@Aspect
@Component
@Order(99)
public class Base64AnnotationAspect {
    @Pointcut("execution(* com.example.swagger.controller..*.*(..))")
    public void base64Pointcut() {
    }

    @Around("base64Pointcut()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        //获取参数值
        Object[] args = joinPoint.getArgs();
        for (Object arg : args) {
            //判断是否为<? extends Collection>
            if (arg instanceof Collection) {
                Iterator<?> iterator = ((Collection<?>) arg).iterator();
                while (iterator.hasNext()) {
                    Object next = iterator.next();
                    if (!isBasicType(next)) {
                        changeBase64(next);
                    }
                }
            }
            //不为基本类型和MAP
            if (!isBasicType(arg)) {
                changeBase64(arg);
            }
        }
        //获取返回response
        Object proceed = joinPoint.proceed(args);
        if (!isBasicType(proceed)) {
            changeBase64(proceed);
        }
        return proceed;
    }

    /**
     * 判断参数是否需要转化为Base64
     */
    private void changeBase64(Object obj) throws IllegalAccessException {
        //判断是否为空
        if (obj == null) {
            return;
        }
        //判断是否为<? extends Collection>
        if (obj instanceof Collection) {
            Iterator<?> iterator = ((Collection<?>) obj).iterator();
            while (iterator.hasNext()) {
                Object next = iterator.next();
                if (!isBasicType(next)) {
                    changeBase64(next);
                }
            }
        }
        //不为基本类型
        if (!isBasicType(obj)) {
            Class<?> cla = obj.getClass();
            Field[] fields = cla.getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                Object o1 = field.get(obj);
                //判断是否为<? extends Collection>
                if (o1 instanceof Collection) {
                    Iterator<?> iterator = ((Collection<?>) o1).iterator();
                    while (iterator.hasNext()) {
                        Object next = iterator.next();
                        if (!isBasicType(next)) {
                            changeBase64(next);
                        }
                    }
                }
                //不为基本类型
                if (!isBasicType(o1)) {
                    changeBase64(o1);
                }
                //为String才进行判断是否转化为BASE64
                if (o1 instanceof String) {
                    for (Annotation annotation : field.getAnnotations()) {
                        //Base64注解的路径
                        String Base64Path = "com.example.swagger.config.annotation.Base64";
                        if (annotation.annotationType().getName().equals(Base64Path)) {
                            field.setAccessible(true);
                            field.set(obj, Base64.getEncoder().encodeToString(field.get(obj).toString().getBytes(StandardCharsets.UTF_8)));
                        }
                    }
                }
            }
        }

    }

    /**
     * 是否为基本类型或者枚举或Map或String
     */
    private Boolean isBasicType(Object obj) {
        return ObjectUtil.isNotNull(obj) &&
                (
                        ObjectUtil.isBasicType(obj)
                                || (obj instanceof Map)
                                || (obj instanceof String)
                                || (obj instanceof Enum)
                );
    }

}

结果说明
1.传进入的original,在response这一层的进行base64转换,对应着返回结果的change
2.传进入的change,在request这一层进行的base64转换,对应着返回结果的original

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,你需要定义一个`@DecryptId`注解,如下所示: ```kotlin @Target(AnnotationTarget.FIELD) @Retention(AnnotationRetention.RUNTIME) annotation class DecryptId ``` 然后,你需要定义一个拦截器来处理`@DecryptId`注解。该拦截器的作用是在进入controller之前,将`IdVo`的属性`id`进行解密操作。假设你使用的是AES对称加密算法,解密的密钥为`key`,解密的偏移量为`iv`,那么你的拦截器可能如下所示: ```kotlin @Component class DecryptIdInterceptor : HandlerInterceptor { @Throws(Exception::class) override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean { if (handler is HandlerMethod) { val method = handler.method val parameters = method.parameters for (i in parameters.indices) { val parameter = parameters[i] if (parameter.isAnnotationPresent(RequestBody::class.java)) { val arg = (handler.arguments[i] as HttpInputMessage).body.readBytes() val objectMapper = ObjectMapper() val idVo = objectMapper.readValue(arg, IdVo::class.java) val fields = idVo.javaClass.declaredFields for (field in fields) { if (field.isAnnotationPresent(DecryptId::class.java)) { field.isAccessible = true val encryptedId = field.get(idVo) as String val decryptedId = decrypt(encryptedId, key, iv) field.set(idVo, decryptedId) } } handler.arguments[i] = idVo } } } return true } private fun decrypt(encryptedText: String, key: String, iv: String): String { val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") val secretKeySpec = SecretKeySpec(key.toByteArray(charset("UTF-8")), "AES") val ivParameterSpec = IvParameterSpec(iv.toByteArray(charset("UTF-8"))) cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec) val decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText)) return String(decryptedBytes, Charset.forName("UTF-8")) } } ``` 最后,你需要在你的`@PostMapping`注解上添加一个`@RequestMapping`注解,将拦截器应用到该controller方法中,如下所示: ```kotlin @PostMapping("/yz") @RequestMapping(consumes = ["application/json"], produces = ["application/json"]) fun yz(@DecryptId @RequestBody idVo: IdVo): IdVo { return idVo } ``` 现在,当你调用`/yz`接口时,`DecryptIdInterceptor`拦截器会自动将`IdVo`的属性`id`进行解密操作,然后进入controller方法中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值