You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现非实体Java类对象中指定字段的加密?

Java非实体类指定字段加密最优实现

针对你不需要加密全对象、仅加密部分字段、且类不是持久化Entity的场景,优先选择低侵入、可复用的实现方案,不要硬编码加密逻辑到字段访问方法里。


最推荐方案:自定义标记注解 + 通用反射加密处理器

这个方案几乎不侵入原有业务代码,一次实现所有类都能复用,维护成本最低。

第一步:定义字段标记注解

先写一个运行时生效的字段注解,专门用来标记需要加密的字段:

import java.lang.annotation.*;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface EncryptField {
}

第二步:给需要加密的字段打标记

回到你的employeeDetail类,只需要在要加密的字段上加注解即可,不需要改动原有字段结构、getter/setter逻辑:

public class employeeDetail{
    private String employeeID;

    @EncryptField
    private String employeeContactNo; // 标记为需要加密

    @EncryptField
    private String employeeAddress; // 标记为需要加密

    private String employeeName;

    // 原有getter、setter、构造方法不需要改动
}

第三步:实现通用加密处理器

写一个通用的处理工具,通过反射扫描对象中带@EncryptField注解的String类型字段,统一执行加解密操作:

import java.lang.reflect.Field;
import java.util.Arrays;

public class FieldEncryptProcessor {
    // 替换成你实际使用的加密实现,比如AES、SM4等对称加密算法即可
    private final CustomEncryptor encryptor;

    public FieldEncryptProcessor(CustomEncryptor encryptor) {
        this.encryptor = encryptor;
    }

    /**
     * 加密对象中所有标记了@EncryptField的字段
     */
    public <T> T encryptFields(T target) throws IllegalAccessException {
        if (target == null) return null;
        Class<?> targetClass = target.getClass();
        for (Field field : listAllFields(targetClass)) {
            // 仅处理带注解、类型为String的字段
            if (field.isAnnotationPresent(EncryptField.class) && field.getType().equals(String.class)) {
                field.setAccessible(true);
                String originVal = (String) field.get(target);
                if (originVal != null && !originVal.isBlank()) {
                    // 加密后写回对象
                    field.set(target, encryptor.encrypt(originVal));
                }
            }
        }
        return target;
    }

    /**
     * 解密对象中所有标记了@EncryptField的字段
     */
    public <T> T decryptFields(T target) throws IllegalAccessException {
        if (target == null) return null;
        Class<?> targetClass = target.getClass();
        for (Field field : listAllFields(targetClass)) {
            if (field.isAnnotationPresent(EncryptField.class) && field.getType().equals(String.class)) {
                field.setAccessible(true);
                String encryptedVal = (String) field.get(target);
                if (encryptedVal != null && !encryptedVal.isBlank()) {
                    field.set(target, encryptor.decrypt(encryptedVal));
                }
            }
        }
        return target;
    }

    // 递归获取类及父类的所有字段,避免父类中标记的字段扫描不到
    private Field[] listAllFields(Class<?> clazz) {
        Field[] declaredFields = clazz.getDeclaredFields();
        Class<?> superClazz = clazz.getSuperclass();
        if (superClazz != null && superClazz != Object.class) {
            Field[] superFields = listAllFields(superClazz);
            Field[] allFields = Arrays.copyOf(declaredFields, declaredFields.length + superFields.length);
            System.arraycopy(superFields, 0, allFields, declaredFields.length, superFields.length);
            return allFields;
        }
        return declaredFields;
    }

    // 自定义加密接口,你自己实现算法逻辑即可
    public interface CustomEncryptor {
        String encrypt(String origin);
        String decrypt(String encrypted);
    }
}

使用的时候只需要初始化一次处理器,传入你的加密实现,后续要处理任何对象直接调用encryptFields/decryptFields方法就行,不需要针对每个类写单独的加解密逻辑。

这个方案的优势:

  • 侵入性极低:哪个字段需要加密就加个注解,不需要改原有业务逻辑
  • 复用性强:所有Java类都可以用这个处理器,不需要重复造轮子
  • 易维护:后续要更换加密算法、新增/移除需要加密的字段,只需要调整注解标记或者加密实现,不需要散改业务代码

适配特定场景的可选方案:序列化层自动加解密

如果你的对象主要用于JSON序列化传输(比如接口返回、缓存存储),可以直接对接你用的JSON框架(Jackson/Fastjson2等)的扩展点,全局配置一次后,带@EncryptField注解的字段会在序列化输出时自动加密、反序列化读入时自动解密,连手动调用处理器的步骤都能省掉。

注意:这个方案仅适合对象流转依赖JSON序列化的场景,如果只是内存中做字段处理,用上面的通用处理器方案更直接。


不推荐的写法

  • 不要在每个字段的getter/setter里硬编码加解密逻辑:后续新增字段、更换算法需要逐个修改类代码,容易漏判,维护成本极高
  • 不要把整个对象做整体加密:这种方式必须解密整个对象才能读取非加密字段,灵活性极差
  • 不要硬编码字段名做反射判断:字段名重构后会直接失效,没有编译期校验,容易出线上故障

内容的提问来源于stack exchange,提问作者Sachin Rana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 11:57:20