You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用Jackson将所有类型的JSON字段值序列化为Base64?

如何让Jackson对所有类型字段值进行Base64编码?

我懂你的需求——不管字段是String、int、long还是自定义对象,都要把它们的JSON输出值转成Base64编码。你现在的序列化器只处理String类型,确实覆盖不了所有场景,下面给你两个实用的方案:

方案一:全局通用Base64序列化器

写一个能处理所有类型的序列化器,注册到ObjectMapper后,所有字段都会自动走Base64编码逻辑。核心思路是针对不同类型做不同的字节转换:

通用序列化器代码

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class GenericBase64Serializer extends StdSerializer<Object> {
    private static final long serialVersionUID = 1L;
    // 单独用一个ObjectMapper处理对象序列化,避免和主Mapper循环引用
    private static final com.fasterxml.jackson.databind.ObjectMapper objectMapper = new com.fasterxml.jackson.databind.ObjectMapper();

    public GenericBase64Serializer() {
        super(Object.class);
    }

    @Override
    public void serialize(Object value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        byte[] bytes;

        // 针对不同类型做字节转换
        if (value instanceof String) {
            bytes = ((String) value).getBytes(StandardCharsets.UTF_8);
        } else if (value instanceof Number || value instanceof Boolean) {
            // 数字、布尔类型先转成字符串再转字节
            bytes = value.toString().getBytes(StandardCharsets.UTF_8);
        } else {
            // 自定义对象或复杂类型,先序列化为JSON字节数组
            bytes = objectMapper.writeValueAsBytes(value);
        }

        // 执行Base64编码并写入JSON
        String encodedValue = Base64.getEncoder().encodeToString(bytes);
        jsonGenerator.writeString(encodedValue);
    }
}

配置ObjectMapper

把这个序列化器注册到你的ObjectMapper里,全局生效:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import java.util.HashMap;

// 初始化模块并注册序列化器
SimpleModule base64Module = new SimpleModule();
base64Module.addSerializer(Object.class, new GenericBase64Serializer());

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(base64Module);

// 测试序列化你的ClassA实例
A instanceOfClassA = new A();
instanceOfClassA.setId(123);
instanceOfClassA.setName("MyTestName");
instanceOfClassA.setDatabase(new HashMap<>() {{ put("dbKey", "dbValue"); }});

objectMapper.writerWithDefaultPrettyPrinter().writeValue(System.out, instanceOfClassA);

方案二:选择性字段编码(更灵活)

如果你不想全局编码所有字段,只想给特定字段加Base64编码,可以用@JsonSerialize注解单独标记字段:

public class A{
    @JsonSerialize(using = GenericBase64Serializer.class)
    int id;
    
    @JsonSerialize(using = GenericBase64Serializer.class)
    String name;
    
    @JsonSerialize(using = GenericBase64Serializer.class)
    Object database;

    // getter和setter方法
}

这种方式不需要全局注册模块,只需要在需要编码的字段上添加注解即可。

注意事项

  • 编码时一定要指定字符集(比如StandardCharsets.UTF_8),避免不同环境下出现乱码问题
  • 如果你的项目里有日期、枚举等特殊类型,可以在序列化器里添加对应的处理分支,比如日期转成ISO格式字符串再编码
  • 处理对象时用单独的ObjectMapper,是为了避免主Mapper已经注册了这个序列化器,导致循环调用的问题

内容的提问来源于stack exchange,提问作者Mostafa Hassan

火山引擎 最新活动