如何在 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
我正在尝试在@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")
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