簡體   English   中英

Spring Boot:我可以將多個對象作為多個@RequestParams 發布到 REST 服務嗎?

[英]Spring Boot: Can I post multiple objects as multiple @RequestParams to a REST service?

使用 Spring Boot,我使用單個資源構建了一個玩具 REST 服務,如下所示:

@RestController
@RequestMapping("/checkout")
public class CheckoutRestController {

    @PostMapping("/book")
    public boolean buyBook(@RequestParam CreditCard creditCard, @RequestParam ShippingAddress shippingAddress) {
        return true;
    }
}

CreditCardShippingAddress都是我編寫的 POJO(普通舊 Java 對象))。

我嘗試使用此有效負載發布到此端點:

{
    "creditCard" : {
        "nameOnCard":"foo",
        "number":12345678,
        "expiryMonth":12,
        "expiryYear":2018,
        "ccv":100
    },
    "shippingAddress" : {
        "steert":"foor",
        "houseNumber":"1a",
        "city":"bar",
        "state":"bazz",
        "country":"buzz",
        "zipCode":"booz"
    },
}

但我得到一個錯誤:

{
    "timestamp": "2018-03-13T11:36:52.745+0000",
    "status": 400,
    "error": "Bad Request",
    "message": "Required CreditCard parameter 'creditCard' is not present",
    "path": "/checkout/book"
}

我知道一個解決方法是將兩個 POJO 包裝在一個請求包裝器中,但我寧願不這樣做,除非我真的必須這樣做。

是否可以發布兩個@RequestParam 注釋對象? 如果是這樣,JSON 會是什么樣子?

@RequestParam參數是查詢參數,不是正文參數。

這意味着您的方法:

@PostMapping("/book")
public boolean buyBook(@RequestParam CreditCard creditCard, @RequestParam 
    ShippingAddress shippingAddress) {

        return true;
}

期望以下請求:

POST /checkout/book?creditCard=<...>&shippingAddress=<...>

但是,Spring 不知道如何將String查詢參數轉換為CreditCardShippingAddress

您可以通過實施Converter來解決此問題,如下所示:

public class StringToCreditCardConverter implements Converter<String, CreditCard> {

    @Override
    public CreditCard convert(String source) {
         <...>
    }
}

但是,我不推薦這樣做,因為它不是請求主體的標准,並且會導致很多混亂和可維護性問題。

相反,推薦的方法如下:

@PostMapping("/book")
public boolean buyBook(@RequestBody BookCreationRequest bookCreationRequest) {
        CreditCard creditCard = bookCreationRequest.getCreditCard();
        ShippingAddress shippingAddress = bookCreationRequest.getShippingAddress();
        ...
}

使用包含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;
}

然后期望請求 JSON 如下:

POST /checkout/book
Payload:
{
    "creditCard": {
        ... 
    },
    "shippingAddress": {
        ...
    }
}

請注意,請求中只能有一個@RequestBody參數。

是 - 創建一個包裝器 Request 對象。 這不是解決方法 - 實際上是推薦的方法。

你在你的 json 中看到你有:

{ //wrapper
 {}, //first complex data object / mapped to pojo
 {} //second complex data object / mapped to pojo
}

1)您可以使用@Valid輕松地將驗證應用於您的 Request 對象,從而驗證兩個 POJO。

2) 您不必擔心負載中的順序。

3) 你錯誤地使用了@RequestParam @RequestBody映射整個 POST 負載。 您必須刪除@RequestParam注釋並改用@RequestBody

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM