当前位置: 首页 > news >正文

Spring Boot中使用MyBatis-Plus和MyBatis拦截器来实现对带有特定注解的字段进行AES加密。

1. 添加依赖
首先,在pom.xml文件中添加必要的依赖项:

xml
深色版本
<dependencies>
    <!-- Spring Boot Starter Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- MyBatis-Plus Spring Boot Starter -->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.4.3</version>
    </dependency>

    <!-- MySQL Connector -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.23</version>
    </dependency>

    <!-- AES加密库 -->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.12.0</version>
    </dependency>
</dependencies>
2. 创建自定义注解
创建一个自定义注解@Encrypt,用于标记需要加密的字段:

java
深色版本
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Encrypt {
}
3. 创建AES加密工具类
创建一个AES加密工具类,用于加密和解密数据:

java
深色版本
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class AesUtil {

    private static final String KEY = "your-secret-key"; // 16位秘钥
    private static final String IV = "your-init-vector"; // 16位初始向量

    public static String encrypt(String value) throws Exception {
        SecretKeySpec secretKeySpec = new SecretKeySpec(KEY.getBytes(), "AES");
        IvParameterSpec ivParameterSpec = new IvParameterSpec(IV.getBytes());
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
        byte[] encrypted = cipher.doFinal(value.getBytes());
        return Base64.getEncoder().encodeToString(encrypted);
    }

    public static String decrypt(String value) throws Exception {
        SecretKeySpec secretKeySpec = new SecretKeySpec(KEY.getBytes(), "AES");
        IvParameterSpec ivParameterSpec = new IvParameterSpec(IV.getBytes());
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
        byte[] original = cipher.doFinal(Base64.getDecoder().decode(value));
        return new String(original);
    }
}
4. 创建MyBatis拦截器
创建一个MyBatis拦截器,用于在插入数据前对带有@Encrypt注解的字段进行加密:

java
深色版本
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;

import java.lang.reflect.Field;

public class EncryptionInterceptor implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        try {
            Class<?> entityClass = metaObject.getOriginalObject().getClass();
            for (Field field : entityClass.getDeclaredFields()) {
                if (field.isAnnotationPresent(Encrypt.class)) {
                    field.setAccessible(true);
                    Object value = field.get(metaObject.getOriginalObject());
                    if (value != null) {
                        String encryptedValue = AesUtil.encrypt(value.toString());
                        field.set(metaObject.getOriginalObject(), encryptedValue);
                    }
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("Encryption failed", e);
        }
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        // 如果需要在更新时也进行加密,可以在这里实现
    }
}
5. 配置拦截器
在Spring Boot的配置类中注册拦截器:

java
深色版本
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyBatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return interceptor;
    }

    @Bean
    public EncryptionInterceptor encryptionInterceptor() {
        return new EncryptionInterceptor();
    }
}
6. 创建实体类和Mapper
创建实体类TestPayRecord,并在需要加密的字段上加上@Encrypt注解:

java
深色版本
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;

@TableName("test_pay_record")
public class TestPayRecord {

    @TableField("request_no")
    private String requestNo;

    @TableField("card_number")
    @Encrypt
    private String cardNumber;

    @TableField("card_phone")
    @Encrypt
    private String cardPhone;

    // Getters and Setters
    public String getrequestNo() {
        return requestNo;
    }

    public void setrequestNo(String requestNo) {
        this.requestNo = requestNo;
    }

    public String getCardNumber() {
        return cardNumber;
    }

    public void setCardNumber(String cardNumber) {
        this.cardNumber = cardNumber;
    }

    public String getCardPhone() {
        return cardPhone;
    }

    public void setCardPhone(String cardPhone) {
        this.cardPhone = cardPhone;
    }
}
创建Mapper接口:

java
深色版本
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.entity.TestPayRecord;

public interface TestPayRecordMapper extends BaseMapper<TestPayRecord> {
}
7. 创建Service和Controller
创建Service类:

java
深色版本
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.entity.TestPayRecord;
import com.example.demo.mapper.TestPayRecordMapper;
import org.springframework.stereotype.Service;

@Service
public class TestPayRecordService extends ServiceImpl<TestPayRecordMapper, TestPayRecord> {
}
创建Controller类:

java
深色版本
import com.example.demo.entity.TestPayRecord;
import com.example.demo.service.TestPayRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class PaymentController {

    @Autowired
    private TestPayRecordService TestPayRecordService;

    @PostMapping("/payment")
    public String createPayment(@RequestBody TestPayRecord record) {
        TestPayRecordService.save(record);
        return "Payment record created successfully";
    }
}
8. 配置数据源
确保你在application.properties或application.yml中正确配置了数据源:

properties
深色版本
# application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/your_database
spring.datasource.username=your_username
spring.datasource.password=your_password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# MyBatis-Plus配置
mybatis-plus.type-aliases-package=com.example.demo.entity
mybatis-plus.mapper-locations=classpath:mapper/*.xml
9. 启动应用
启动Spring Boot应用,并使用Postman或其他工具发送POST请求来测试插入功能:

json
深色版本
{
    "requestNo": "123456",
    "cardNumber": "1234567890123456",
    "cardPhone": "13800000000"
}
这样,cardNumber和cardPhone字段在插入数据库之前会被自动加密。

http://www.lryc.cn/news/461309.html

相关文章:

  • Python GUI 编程:tkinter 初学者入门指南——框架、标签框架
  • Mac 远程 Windows 等桌面操作系统工具 Microsoft Remote Desktop for Mac 下载安装详细使用教程
  • 初级网络工程师之从入门到入狱(四)
  • MinIO配置与使用
  • 【漏洞复现】SpringBlade menu/list SQL注入漏洞
  • 物联网智能项目(含案例说明)
  • 【YOLOv8改进】 YOLOv8 更换骨干网络之GhostNetV3步骤详解
  • 成绩查询小程序,家长查分超方便~
  • 鸿蒙开发(NEXT/API 12)【上传下载文件】远场通信场景
  • 快速理解AUTOSAR CP的软件架构层次以及各层的作用
  • 【Unity】Unity中接入Admob聚合广告平台,可通过中介接入 AppLovin,Unity Ads,Meta等渠道的广告
  • PythonExcel批量pingIP地址
  • 软媒市场新蓝海:软文媒体自助发布与自助发稿的崛起
  • 【笔记】Day2.5.1查询运费模板列表(未完
  • 阿基米德螺旋线等距取点
  • 2024年全球增强现实(AR)市场分析报告
  • 探索 NetworkX:Python中的网络分析利器
  • Python知识点:基于Python技术,如何使用AirSim进行无人机模拟
  • 《中国林业产业》是什么级别的期刊?是正规期刊吗?能评职称吗?
  • 私域流量下的白酒新传奇:半年破五千万的营销策略揭秘
  • Tomcat 配置:方便运行 Java Web 项目
  • Spring Boot知识管理:机器学习与AI集成
  • Superset SQL模板使用
  • 算法工程师重生之第二十七天(合并区间 单调递增的数字 监控二叉树 总结)
  • 前端开发基础NodeJS+NPM基本使用(零基础入门)
  • 深度学习 nd.random.normal()
  • Redis Geo 数据类型解析:基于 ZSET 的高效地理位置管理0708
  • 爬虫post收尾以及cookie加代理
  • c++STL——map与set的使用及介绍
  • Vxe UI vue vxe-table select 下拉框选项列表数据量超大过大时卡顿解决方法