如何使用Jackson将原始JSON字符串注入到实体类指定字段中?
Jackson 原生支持实现该需求,无需引入第三方依赖,以下是通用可落地的实现方案:
实现步骤
1. 定义标记接口
先定义一个公共接口,用于识别需要保留原始JSON的实体类:
public interface HasOriginalJson { void setOriginalJson(String json); }
2. 改造实体类
让你的业务实体类实现上述接口:
class MyModel implements HasOriginalJson { public int a; public String b; public String originalJson; @Override public void setOriginalJson(String json) { this.originalJson = json; } }
3. 实现通用反序列化器
自定义Jackson反序列化器,自动注入原始JSON到实体类:
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; public class OriginalJsonDeserializer<T extends HasOriginalJson> extends StdDeserializer<T> { private final Class<T> targetClass; public OriginalJsonDeserializer(Class<T> targetClass) { super(targetClass); this.targetClass = targetClass; } @Override public T deserialize(JsonParser parser, DeserializationContext context) throws IOException { // 读取当前节点 JsonNode node = parser.getCodec().readTree(parser); // 生成当前节点的原始JSON字符串 String rawJson = node.toString(); // 反序列化节点到目标实体 T instance = parser.getCodec().treeToValue(node, targetClass); // 注入原始JSON instance.setOriginalJson(rawJson); return instance; } // 快捷注册方法 public static <T extends HasOriginalJson> void register(ObjectMapper mapper, Class<T> targetClass) { SimpleModule module = new SimpleModule(); module.addDeserializer(targetClass, new OriginalJsonDeserializer<>(targetClass)); mapper.registerModule(module); } }
4. 实际使用
// 初始化ObjectMapper并注册反序列化器 ObjectMapper objectMapper = new ObjectMapper(); OriginalJsonDeserializer.register(objectMapper, MyModel.class); // 单个对象解析场景 String singlePayload = """ {"a": 1, "b": "hello"} """; MyModel model = objectMapper.readValue(singlePayload, MyModel.class); // 数组解析场景 String arrayPayload = """ [ {"a": 1, "b": "hello"}, {"a": 2, "b": "bye"} ] """; MyModel[] models = objectMapper.readValue(arrayPayload, MyModel[].class);
注意事项
如果要求originalJson完全和输入的原始字符串(包括空格、换行符等格式)完全一致,可以在解析时通过JsonParser获取当前节点在输入流中的起止位置,直接截取原始输入字符串即可,无需使用JsonNode.toString()。
内容的提问来源于stack exchange,提问作者diziaq
相关产品推荐
相关产品推荐

