Spring Boot+JPA场景下使用org.springframework.data.geo.Point接收Postman请求时触发InvalidDefinitionException问题求助
解决Spring Boot中Jackson反序列化
org.springframework.data.geo.Point的问题 这个问题我之前在项目里也碰到过!本质是Jackson没法自动处理org.springframework.data.geo.Point的反序列化——因为这个类既没有无参构造函数,也没有标注能让Jackson识别的属性构造器,所以它不知道怎么把你请求里的{x:..., y:...}对象转成Point实例。下面给你三种靠谱的解决办法,按需选择:
方法1:给字段添加自定义反序列化器(快速解决单个场景)
如果只有CreationRequest这一个类用到Point,直接在字段上标注自定义反序列化器最省事:
- 先写一个Point的反序列化器:
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 parser, DeserializationContext context) throws IOException { JsonNode node = parser.getCodec().readTree(parser); double x = node.get("x").asDouble(); double y = node.get("y").asDouble(); return new Point(x, y); } }
- 然后在
CreationRequest的location字段上关联这个反序列化器:
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import org.springframework.data.geo.Point; public class CreationRequest { private String building; @JsonDeserialize(using = PointDeserializer.class) private Point location; // 记得添加getter、setter,或者用Lombok的@Data注解简化 }
方法2:全局注册反序列化器(适合多场景复用)
如果你的项目里很多地方都需要处理Point的反序列化,全局配置更高效,不用每个字段都加注解:
写一个Jackson配置类,把自定义反序列化器注册到Spring的ObjectMapper里:
import com.fasterxml.jackson.databind.module.SimpleModule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.geo.Point; @Configuration public class JacksonConfig { @Bean public SimpleModule pointDeserializationModule() { SimpleModule module = new SimpleModule(); module.addDeserializer(Point.class, new PointDeserializer()); return module; } }
这样所有需要反序列化Point的地方都会自动用这个逻辑,一劳永逸。
方法3:通过构造器手动转换(无需额外类)
如果不想写自定义反序列化器,也可以在CreationRequest的构造器里手动处理location的转换:
import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import org.springframework.data.geo.Point; import java.util.Map; public class CreationRequest { private String building; private Point location; @JsonCreator public CreationRequest( @JsonProperty("building") String building, @JsonProperty("location") Map<String, Double> location) { this.building = building; this.location = new Point(location.get("x"), location.get("y")); } // 记得添加无参构造函数,给JPA和Jackson的其他场景使用 public CreationRequest() {} // getter、setter省略 }
这种方式比较直接,但如果后续location的JSON结构有变化,需要同步修改构造器里的逻辑,灵活性稍差。
用上面任意一种方法处理后,再发送你原来的Postman请求:
{ "building":"114", "location": { "x":30.025622148122764, "y": 31.482759761365305 } }
应该就能正常反序列化,不会再抛出InvalidDefinitionException了。
内容的提问来源于stack exchange,提问作者Omar Abo Elsoud
相关产品推荐
相关产品推荐

