如何在 Spring boot Api post 方法中接收定制的 JSON 对象

How to receive customized JSON Object in Spring boot Api post Method

我正在尝试在@RequestBody 中接收一个我不知道的 JSON 对象,即 JSON 对象可以是任何长度和数据。

假设,JSON可能如下所示

{'seqNo': 10 }

{'country': 'US', 'state': 'CA'}

{'customer': 'Alex', product: 'UPS', date:'25-Mar-2018'}

并且在 Spring 引导 Api 中,我有一个方法来接收那个 JSON 对象。

@PostMapping(value = "/lookup")
public ResponseEntity<AppResponse> getLookup(@RequestBody LookupRequestObject lookupRequestObject) {

        // THIS METHOD KNOWS WHICH FIELD TO USE
        // FURTHER LOGIC WOULD BE HERE.


        return ResponseEntity.ok(response);

    }

我已阅读有关 Jackson 序列化的内容,但仍在寻找解决方案。

Customize the Jackson ObjectMapper

如有任何帮助,我们将不胜感激。

您可以只使用地图作为输入。 然后你可以根据它包含的字段类型访问地图中的字段。

@PostMapping(value = "/lookup")
public ResponseEntity<AppResponse> getLookup(@RequestBody Map<String, Object> lookupRequestObject) {

    // THIS METHOD KNOWS WHICH FIELD TO USE
    // FURTHER LOGIC WOULD BE HERE.

    return ResponseEntity.ok(response);
}

如果 JSON object 结构未知,您可以随时使用 Map<String, Object> 类型并将其转换为 POJO 或直接在 Map 上工作。如果你需要 POJO 你可以使用 convertValue 方法:

@PostMapping(value = "/lookup")
public ResponseEntity<AppResponse> getLookup(@RequestBody Map<String, Object> payload) {
    // read map
    ObjectMapper objectMapper = new ObjectMapper();
    if (payload.containsKey("seqNo")) {
        Sequence seq = objectMapper.convertValue(payload, Sequence.class);
        // other logic
    } else if (payload.containsKey("country")) {
        Country country = objectMapper.convertValue(payload, Country.class);
    }
    // the same for other types

    // FURTHER LOGIC WOULD BE HERE.
    return ResponseEntity.ok(response);
}

您也可以尝试反序列化为 com.fasterxml.jackson.databind.JsonNode,但它会将控制器与 Jackson 绑定,这从另一端来看并不好。

@Patrick Adler 的回答绝对正确。您可以使用 Map 作为方法的参数。两个重要的补充: Map 对应于 JSON 对象,因此当一个 JSON 对象被传递给你的方法时 Spring (默认使用 Jackson)会将它转换为 map,因此不需要额外的代码。还要确保您可以添加到您希望收到 JSON 输入的注释中: 所以改变行

@PostMapping(value = "/lookup")

@PostMapping(value = "/lookup", headers = "Accept=application/json")

最后,您发布的输入不是有效的单个 JSON 对象。它是 3 个独立的 JSON 对象。因此,您要么期望包含 JSON 个对象的 JSON 数组,要么期望单个 JSON 对象。如果您期望 JSON 数组,那么在您的方法中使用 List<Map<String, Object>> 而不是 Map<String, Object> 参数,因此您的解决方案应该看起来是

@PostMapping(value = "/lookup", headers = "Accept=application/json")
public ResponseEntity<AppResponse> getLookup(@RequestBody Map<String, Object> lookupRequestObject) {

    // THIS METHOD KNOWS WHICH FIELD TO USE
    // FURTHER LOGIC WOULD BE HERE.

    return ResponseEntity.ok(response);
}

或相同但使用 List<Map<String, Object>> 参数而不是 map