如何在 Spring Boot Api post 方法中接收自定义的 JSON 对象
Posted
技术标签:
【中文标题】如何在 Spring Boot Api post 方法中接收自定义的 JSON 对象【英文标题】:How to receive customized JSON Object in Spring boot Api post Method 【发布时间】:2019-08-23 09:50:55 【问题描述】:我试图在@RequestBody 中接收一个我不知道的 JSON 对象,即 JSON 对象可以是任何长度和数据。
假设JSON可以如下所示
'seqNo': 10
'country': 'US', 'state': 'CA'
'customer': 'Alex', product: 'UPS', date:'25-Mar-2018'
在 Spring Boot 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
任何帮助将不胜感激。
【问题讨论】:
您可以接受请求正文为String
,然后自己使用 Jackson 将字符串反序列化为相关类。
@Arnaud,相关类意味着每个 JSON(如上所示)都有相关类。
【参考方案1】:
您可以只使用地图作为输入。 然后您可以根据它包含的字段类型访问地图中的字段。
@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);
【讨论】:
【参考方案2】:如果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
绑定,这从另一边来说不好。
【讨论】:
MapJava
中,泛型被替换为随处可见的转换,并且工作正常。所以,以 Integer seq = (Integer)payload.get("seqNo")
的方式使用 map 就可以了。【参考方案3】:
@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>>
参数而不是仅映射
【讨论】:
更安全一点的是List<Object>
而不是List<Map<String, Object>>
,因为在原始数组[1,2,3]
的情况下,它会默认工作。
是的,我有一些复杂的 JSON,例如 'seqNo': 10, 'sort': 'field': 'ctry', 'desc': 0 'filter': ' field': 'region', 'operator': 'startsWith', 'value': 'europe' page: 0, size: 20, userData: ...
@TAB,你的 JSON 很好,在这种情况下你的参数仍然是 Map以上是关于如何在 Spring Boot Api post 方法中接收自定义的 JSON 对象的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring Boot Api post 方法中接收自定义的 JSON 对象
如何使用 Postman 表单数据将 POST 请求发送到 Spring Boot REST API?
Spring Boot - 模拟对外部 API 的 POST REST 请求
Spring Boot - 如何通过带有查询参数的 url 发送 POST 请求并将响应存储在方法中?