簡體   English   中英

春天@RequestBody不使用pojo?

[英]Spring @RequestBody without using a pojo?

我正在使用Spring Boot,並且在控制器中定義了這樣的方法

@PostMapping("/update)
public void update(@RequestBody User user) {
    ...
}

但是,在我從客戶端(例如前端或郵遞員)發出的發帖請求中,我有類似以下內容:

{
    "firstName" : "John",
    "lastName" : "Doe",
    "id" : 1234,
    "metaInfoId" : "5457sdg26sg4636"
}

事情是我的用戶pojo中只有firstNameidlastName實例字段,但是在我的請求中我have to send metaInfoId來滿足其他一些需求。 那么如何在上面的控制器方法中檢索或分離metaInfoIdUser模型?

我是否必須創建另一個名為UserModelRequest模型類,並將所有User字段與metaInfoId字段一起添加,然后使用@RequestBody 有沒有一種方法可以簡單地從請求中刪除metaInfoId ,然后取出其他所有內容並將其轉儲到User pojo中? 例如,您可以在nodejs中輕松地做到這一點(只需拼接對象並獲取所需的內容)。

那么有沒有一種方法可以在Java Spring中執行而不必創建另一個模型類?

您可以使用@JsonIgnoreProperties(ignoreUnknown = true)注釋POJO,以便忽略其中不包含的字段。 防爆

@JsonIgnoreProperties(ignoreUnknown = true)
public class User {
    private int id;
    private String firstName;
    private String lastName;

    ... getters & setters ...
}

此外,您不應在其余請求的正文中包含元數據。 此信息的正確位置將在標題中。 這會將您的方法簽名更改為:

@PostMapping("/update)
public void update(@RequestBody User user, @RequestHeader(value="metaInfoId") String metaInfoId) {
    ...
}

如果必須在請求中添加信息,則需要更新User pojo類以包括此字段(或者讓它使用metaInfoId字段擴展類)

最后,您真的不想創建新類型。 您可以更改簽名以接受地圖並檢索必要的信息,例如:

@PostMapping("/update)
public void update(@RequestBody Map<String, Object> userMap) {
    String metaInfoId = userMap.get("metaInfoId");

    ObjectMapper mapper = new ObjectMapper(); // jackson's objectmapper
    final User user = mapper.convertValue(userMap, User.class);
}

從這個問題中我了解到您可能需要兩種情況:

  • 在JSON中發送一個屬性,該屬性在User對象中沒有相應的字段。 在這種情況下,您仍然需要將User對象與提供的字段一起使用,並忽略JSON中提供的其余部分
  • 在JSON中發送其他屬性,您仍然需要在User對象中捕獲它們, 而無需在對象中專門定義那些額外的屬性。

我認為在這兩種情況下,使用Jackson都比Gson更好,因為它對對象具有更豐富的編組控制。 因此,我的以下解決方案假定您將在Spring Web上使用Jackson-傑克遜的maven依賴關系如下:

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
</dependency>

第一案

在這種情況下,當傑克遜將JSON反序列化為User對象時,您需要忽略metaInfoId屬性。 為此,請將此批注添加到User類的頂部。

@JsonIgnoreProperties(ignoreUnknown = true)
class User {
    private String firstName;
    private String lastName;

    // the rest of the class definition
}

第二種情況

在第二種情況下,您仍然需要捕獲額外的屬性。 我建議添加一個接受所有額外的未定義屬性的catch HashMap ,您可以通過鍵/值對其進行訪問。 為此,您需要將以下內容添加到您的User類中,或者更好地創建一個包含該代碼的抽象類,以便User擴展。

class User {
    private String firstName;
    private String lastName;
    private Map<String, Object> extra;

    @JsonAnySetter
    public void addExtra(final String key, final Object value){
        this.extra.put(key, value);  
    }

    @JsonAnyGetter
    public Map<String, Object> getExtra() {
        return Collections.unmodifiableMap(this.extra);
    }

    // the rest of the class definition
}

希望這可以幫助

暫無
暫無

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

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