[英]Spring Boot: Can I post multiple objects as multiple @RequestParams to a REST service?
Using Spring Boot I've build a toy REST service with a single resource like so:使用 Spring Boot,我使用单个资源构建了一个玩具 REST 服务,如下所示:
@RestController
@RequestMapping("/checkout")
public class CheckoutRestController {
@PostMapping("/book")
public boolean buyBook(@RequestParam CreditCard creditCard, @RequestParam ShippingAddress shippingAddress) {
return true;
}
}
Both CreditCard
and ShippingAddress
are POJOs (plain old Java objects) that I've coded up). CreditCard
和ShippingAddress
都是我编写的 POJO(普通旧 Java 对象))。
I've tried posting to this endpoint with this payload:我尝试使用此有效负载发布到此端点:
{
"creditCard" : {
"nameOnCard":"foo",
"number":12345678,
"expiryMonth":12,
"expiryYear":2018,
"ccv":100
},
"shippingAddress" : {
"steert":"foor",
"houseNumber":"1a",
"city":"bar",
"state":"bazz",
"country":"buzz",
"zipCode":"booz"
},
}
But I get an error:但我得到一个错误:
{
"timestamp": "2018-03-13T11:36:52.745+0000",
"status": 400,
"error": "Bad Request",
"message": "Required CreditCard parameter 'creditCard' is not present",
"path": "/checkout/book"
}
I know a workaround would be to wrap both POJOs in a request wrapper but I'd rather not unless I really have to.我知道一个解决方法是将两个 POJO 包装在一个请求包装器中,但我宁愿不这样做,除非我真的必须这样做。
Is it possible to post two @RequestParam annotated objects?是否可以发布两个@RequestParam 注释对象? If so, what would the JSON look like?如果是这样,JSON 会是什么样子?
@RequestParam
parameters are query parameters, not body parameters. @RequestParam
参数是查询参数,不是正文参数。
This means that your method:这意味着您的方法:
@PostMapping("/book")
public boolean buyBook(@RequestParam CreditCard creditCard, @RequestParam
ShippingAddress shippingAddress) {
return true;
}
Expects the following request:期望以下请求:
POST /checkout/book?creditCard=<...>&shippingAddress=<...>
However, Spring doesn't know how to convert a String
query parameter to CreditCard
or to ShippingAddress
.但是,Spring 不知道如何将String
查询参数转换为CreditCard
或ShippingAddress
。
You might solve this by implementing a Converter
, as follows:您可以通过实施Converter
来解决此问题,如下所示:
public class StringToCreditCardConverter implements Converter<String, CreditCard> {
@Override
public CreditCard convert(String source) {
<...>
}
}
However, I do not recommend this as it is not the standard for request bodies and would cause quite a lot of confusion and maintainability issues.但是,我不推荐这样做,因为它不是请求主体的标准,并且会导致很多混乱和可维护性问题。
Instead, the recommended way is as follows:相反,推荐的方法如下:
@PostMapping("/book")
public boolean buyBook(@RequestBody BookCreationRequest bookCreationRequest) {
CreditCard creditCard = bookCreationRequest.getCreditCard();
ShippingAddress shippingAddress = bookCreationRequest.getShippingAddress();
...
}
With the bookCreationRequest
containing the CreditCard
and ShippingAddress
fields (note: you could use eg lombok
to reduce the boilerplate code):使用包含CreditCard
和ShippingAddress
字段的bookCreationRequest
(注意:您可以使用例如lombok
来减少样板代码):
public class BookCreationRequest {
private ShippingAddress shippingAddress;
private CreditCredit creditCard;
public ShippingAddress getShippingAddress() {...}
public CreditCard getCreditCard() {...}
public BookCreationRequest(ShippingAddress shippingAddress, CreditCard creditCard) {
this.creditCard = creditCard;
this.shippingAddress = shippingAddress;
}
Which would then expect a request JSON as follows:然后期望请求 JSON 如下:
POST /checkout/book
Payload:
{
"creditCard": {
...
},
"shippingAddress": {
...
}
}
Note that there can only be a single @RequestBody
parameter in a request.请注意,请求中只能有一个@RequestBody
参数。
Yes - create a wrapper Request object.是 - 创建一个包装器 Request 对象。 It's not a workaround - it's actually the recommended approach.这不是解决方法 - 实际上是推荐的方法。
You see in your json you have:你在你的 json 中看到你有:
{ //wrapper
{}, //first complex data object / mapped to pojo
{} //second complex data object / mapped to pojo
}
1) You can easily apply validation to your Request object with @Valid
and hence validate both POJOs. 1)您可以使用@Valid
轻松地将验证应用于您的 Request 对象,从而验证两个 POJO。
2) You don't have to worry about the order in the payload. 2) 您不必担心负载中的顺序。
3) You're using @RequestParam
incorrectly. 3) 你错误地使用了@RequestParam
。 @RequestBody
is what maps the whole POST payload. @RequestBody
映射整个 POST 负载。 You have to remove the @RequestParam
annotation and use @RequestBody
instead.您必须删除@RequestParam
注释并改用@RequestBody
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.