简体   繁体   English

Spring Boot:我可以将多个对象作为多个@RequestParams 发布到 REST 服务吗?

[英]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). CreditCardShippingAddress都是我编写的 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查询参数转换为CreditCardShippingAddress

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):使用包含CreditCardShippingAddress字段的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.

相关问题 我可以将多个对象发布到 REST 服务但只有一个作为@RequestParams 以及如何从 PostMan 调用它吗 - Can I post multiple objects to a REST service but only one as @RequestParams and how to call it from PostMan 如何在 Spring Boot REST 中处理未知数量的 RequestParams? - How do I handle an unknown number of RequestParams in Spring Boot REST? Spring REST API 多个 RequestParams 与控制器实现 - Spring REST API multiple RequestParams vs controller implementation 在 Spring Boot 2 中,我如何接受 LocalDates 作为 RequestParams - In Spring Boot 2 how can I accept LocalDates as RequestParams 找不到带有Rest服务的RequestParams - Not finding RequestParams with Rest service Android中的后期请求Spring Boot Rest服务出现I / O错误 - I/O Error On Post Request Spring Boot Rest Service In Android Spring Boot Rest Web Service 在获取请求中获取多个参数 - Spring Boot Rest Web Service fetching multiple parameters in Get Request 您可以在多个线程上启动Spring Boot Rest应用程序吗? - Can you launch a Spring boot rest application on multiple threads? Spring Rest - 发布多个文件 - Spring Rest - Post multiple files 如何在 Spring Data Jpa 中过滤作为 RequestParams 传递的多个参数? - How to have filtering of multiple parameters passed as RequestParams in Spring Data Jpa?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM