Spring @Requestbody 序列化数组的数组(坐标)
Spring @Requestbody serialize Array of Arrays (Coordinates)
我的 RestController 方法
@PostMapping(value = "/search/spatial", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<Point>> findSpatialResults(@RequestBody List<Point> points) {
return ResponseEntity.ok(points);
}
以
形式接收polygon/multipolygon的坐标
[
[
144.66796875000003,
-23.21549308957186
],
...
[
144.39629254087737,
-23.290953516004656
],
]
因为我的坐标不是物体,比如
[{
"x": 144.66796875000003,
"y": -23.21549308957186
}]
Jackson 无法映射它们(无法从 START_ARRAY 令牌 中反序列化 java.awt.Point
的实例)
如何将 Array of Arrays 序列化为一个 ArrayList<Point>
?
创建自定义反序列化器是一种方法,另一种方法是像这样手动完成:
@PostMapping(value = "/search/spatial", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<Point>> findSpatialResults(@RequestBody List<List<Integer>> points) {
List<Point> parsedPoints = points.stream().map(it -> new Point(it.get(0), it.get(1))).collect(Collectors.toList());
return ResponseEntity.ok(parsedPoints);
}
输入
[
[
144,
-23
],
[
144,
-23
]
]
产生结果
[
{
"x": 144.0,
"y": -23.0
},
{
"x": 144.0,
"y": -23.0
}
]
编辑: 来自双精度数组的 java.awt.Point
的简单反序列化器(缺少适当的错误处理):
public class PointDeserializer extends JsonDeserializer<Point> {
@Override
public Point deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
ObjectCodec oc = jp.getCodec();
JsonNode node = oc.readTree(jp);
ArrayNode arrayNode = (ArrayNode) node;
double x = arrayNode.get(0).doubleValue();
double y = arrayNode.get(1).doubleValue();
return new Point((int) x, (int) y);
}
}
那么,如果你使用Spring,我们应该像这样注册这个反序列化器:
@Bean
public Module pointDeserializer() {
SimpleModule module = new SimpleModule();
module.addDeserializer(Point.class, new PointDeserializer());
return module;
}
并且控制器将正确解析 List<Point>
:
@PostMapping(value = "/search/spatial", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<Point>> findSpatialResults(@RequestBody List<Point> points) {
return ResponseEntity.ok(points);
}
我的 RestController 方法
@PostMapping(value = "/search/spatial", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<Point>> findSpatialResults(@RequestBody List<Point> points) {
return ResponseEntity.ok(points);
}
以
形式接收polygon/multipolygon的坐标[
[
144.66796875000003,
-23.21549308957186
],
...
[
144.39629254087737,
-23.290953516004656
],
]
因为我的坐标不是物体,比如
[{
"x": 144.66796875000003,
"y": -23.21549308957186
}]
Jackson 无法映射它们(无法从 START_ARRAY 令牌 中反序列化 java.awt.Point
的实例)
如何将 Array of Arrays 序列化为一个 ArrayList<Point>
?
创建自定义反序列化器是一种方法,另一种方法是像这样手动完成:
@PostMapping(value = "/search/spatial", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<Point>> findSpatialResults(@RequestBody List<List<Integer>> points) {
List<Point> parsedPoints = points.stream().map(it -> new Point(it.get(0), it.get(1))).collect(Collectors.toList());
return ResponseEntity.ok(parsedPoints);
}
输入
[
[
144,
-23
],
[
144,
-23
]
]
产生结果
[
{
"x": 144.0,
"y": -23.0
},
{
"x": 144.0,
"y": -23.0
}
]
编辑: 来自双精度数组的 java.awt.Point
的简单反序列化器(缺少适当的错误处理):
public class PointDeserializer extends JsonDeserializer<Point> {
@Override
public Point deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
ObjectCodec oc = jp.getCodec();
JsonNode node = oc.readTree(jp);
ArrayNode arrayNode = (ArrayNode) node;
double x = arrayNode.get(0).doubleValue();
double y = arrayNode.get(1).doubleValue();
return new Point((int) x, (int) y);
}
}
那么,如果你使用Spring,我们应该像这样注册这个反序列化器:
@Bean
public Module pointDeserializer() {
SimpleModule module = new SimpleModule();
module.addDeserializer(Point.class, new PointDeserializer());
return module;
}
并且控制器将正确解析 List<Point>
:
@PostMapping(value = "/search/spatial", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<Point>> findSpatialResults(@RequestBody List<Point> points) {
return ResponseEntity.ok(points);
}