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);
}