如何将带@JsonValue的Jackson值对象序列化为无引号纯字符串?
解决Jackson序列化@JsonValue值对象时去除双引号的通用方法
当使用@JsonValue注解的类返回字符串类型时,Jackson默认会将其序列化为带双引号的JSON字符串。以下是两种无需修改原类的通用解决方案:
方案一:通过JsonNode提取纯文本值
这是最简洁的实现方式,利用Jackson的JsonNode直接获取@JsonValue对应的原始值:
ObjectMapper objectMapper = new ObjectMapper(); ValueType valueType = new ValueType("1234"); // 将对象转换为JsonNode后提取纯文本 String plainValue = objectMapper.valueToTree(valueType).asText(); System.out.println(plainValue); // 输出:1234
原理:valueToTree会根据@JsonValue注解解析对象生成TextNode,asText()方法直接返回节点的原始字符串内容,不会包含JSON格式的双引号。
方案二:自定义序列化器全局配置
如果需要保持使用writeValueAsString方法直接输出纯值,可以自定义序列化器并注册到ObjectMapper:
步骤1:实现自定义序列化器
public class RawJsonValueSerializer extends JsonSerializer<Object> { @Override public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException { // 解析类的@JsonValue注解信息 BeanDescription beanDesc = serializers.getConfig().introspect(serializers.constructType(value.getClass())); JsonValue.Value valueInfo = beanDesc.findJsonValue(); if (valueInfo != null) { Object rawValue = valueInfo.getValueHandler().getValue(value); if (rawValue instanceof String) { // 直接写入原始字符串,跳过JSON引号包裹 gen.writeRawValue((String) rawValue); } else { // 非字符串类型按默认逻辑序列化 serializers.defaultSerializeValue(rawValue, gen); } } else { // 无@JsonValue注解的类按默认逻辑处理 serializers.defaultSerializeValue(value, gen); } } }
步骤2:注册序列化器到ObjectMapper
ObjectMapper objectMapper = new ObjectMapper(); SimpleModule customModule = new SimpleModule(); // 注册序列化器,全局生效 customModule.addSerializer(Object.class, new RawJsonValueSerializer()); objectMapper.registerModule(customModule); ValueType valueType = new ValueType("1234"); String plainValue = objectMapper.writeValueAsString(valueType); System.out.println(plainValue); // 输出:1234
方案说明
- 该配置只需一次,后续所有带
@JsonValue注解且返回字符串的类都会按此规则序列化; - 若
@JsonValue返回非字符串类型,会自动 fallback 到Jackson默认序列化逻辑。
内容的提问来源于stack exchange,提问作者Hein Blöd
相关产品推荐
相关产品推荐

