如何使用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




