使用Lombok的Circle类反序列化第三方Point类失败,如何解决?
解决Jackson反序列化org.springframework.data.geo.Point的问题
你遇到的核心问题是Jackson无法通过无参构造方法实例化第三方的Point类,且仅添加@JsonDeserialize(builder = PointBuilder.class)注解不足以让Jackson识别自定义Builder,以下是几种可行的解决方案:
方案一:完善Builder并添加Jackson识别注解
仅指定Builder类不够,需要给Builder添加Jackson所需的注解,让其能被正确识别:
- 实现带Jackson注解的
PointBuilder类:
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; @JsonPOJOBuilder(withPrefix = "") // 指定方法前缀为空,适配x()、y()命名 public class PointBuilder { private double x; private double y; public PointBuilder x(double x) { this.x = x; return this; } public PointBuilder y(double y) { this.y = y; return this; } public Point build() { return new Point(x, y); } }
- 保持
Circle类的注解不变,Jackson会通过这个Builder完成Point的反序列化:
@Getter @Setter @NoArgsConstructor public class Circle { private double radius; @JsonDeserialize(builder = PointBuilder.class) private Point center; ... }
如果Builder方法命名为withX()、withY(),可以省略@JsonPOJOBuilder的withPrefix参数,默认前缀为with。
方案二:用Mixin类给第三方构造方法添加Jackson注解
由于无法直接修改第三方Point类的源码,可以通过Jackson的Mixin机制,给其构造方法添加@JsonCreator注解:
- 创建Mixin抽象类:
import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import org.springframework.data.geo.Point; public abstract class PointMixin { @JsonCreator public PointMixin(@JsonProperty("x") double x, @JsonProperty("y") double y) {} }
- 在Jackson的
ObjectMapper中注册这个Mixin:
ObjectMapper objectMapper = new ObjectMapper(); objectMapper.addMixIn(Point.class, PointMixin.class);
这样Jackson会通过Point(double x, double y)构造方法完成反序列化。
方案三:自定义JsonDeserializer
如果上述方案不适用,可以直接实现自定义反序列化器:
- 编写
PointDeserializer类:
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonNode; import org.springframework.data.geo.Point; import java.io.IOException; public class PointDeserializer extends JsonDeserializer<Point> { @Override public Point deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { JsonNode node = p.getCodec().readTree(p); double x = node.get("x").asDouble(); double y = node.get("y").asDouble(); return new Point(x, y); } }
- 修改
Circle类的注解,指定使用自定义反序列化器:
@Getter @Setter @NoArgsConstructor public class Circle { private double radius; @JsonDeserialize(using = PointDeserializer.class) private Point center; ... }
内容的提问来源于stack exchange,提问作者Eric
相关产品推荐
相关产品推荐

