2017-10-06 55 views
1

在Spring Boot Controller方法中,如何獲取POST的主體?我見過的所有例子都使用@RequestBody。如何在不使用@RequestBody的情況下獲取身體?Spring @RequestMapping方法無@RequestBody

我在寫一個方法來處理Slack事件。當Slack POST一個事件時,主體是JSON並且通常包含一個「用戶」鍵。根據事件的類型,「user」的值可以是字符串或對象。正因爲如此,我不能創建一個類,寫

@RequestMapping(path = "/slackRequest", method = RequestMethod.POST) 
    public String handleSlackRequest(@RequestBody final SlackRequest slackRequest) 

答:實現由@ChiDov建議的方法,解決的辦法是保持@RequestBody,進口

import com.fasterxml.jackson.annotation.JsonSetter; 
import com.fasterxml.jackson.databind.DeserializationFeature; 
import com.fasterxml.jackson.databind.JsonNode; 
import com.fasterxml.jackson.databind.ObjectMapper; 

定義用戶字段(和一個新的字段來存儲「用戶」,如果它是一個簡單的字符串值)作爲

@OneToOne 
private SlackEventUser user; 
private String slackUserId; 

並定義它的設置器方法

@JsonSetter("user") 
public void setUser(JsonNode userNode) { 
    ObjectMapper mapper = new ObjectMapper(); 
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 
    if (userNode.isObject()) { 
     SlackEventUser slackEventUser = mapper.convertValue(userNode, SlackEventUser.class); 
     this.user = slackEventUser; 
    } else { 
     String userString = mapper.convertValue(userNode, String.class); 
     this.slackUserId = userString; 
     this.user = null; 
    } 
} 
+0

只要接受一個'String'和根據內容手動映射它? –

+0

@DarrenForsythe反序列化器知道「{」是對象的開始,而不是String:「無法讀取HTTP消息:org.springframework.http.converter.HttpMessageNotReadableException:無法讀取文檔:無法反序列化java實例.lang.String超出START_OBJECT標記「 –

回答

0

更新:我會讓你的DTO喜歡:

Class SlackRequest{ 
    ... 
    private String eventType; 
    private JsonNode user; 
    ... 
    public String getUser(){ 
     return user.asText(); 
    } 
} 

和控制器:

@RequestMapping(path = "/slackRequest", method = RequestMethod.POST) 
    public String handleSlackRequest(@RequestBody final SlackRequest slackRequest){ 
    if(slackRequest.getEventType == "objectEvent"){ 
     SomeObject user = mapper.convertValue(slackRequest.getUser(), SomeObject.class); 
     // do something with the object 
    }else{ 
    // do something with the user string 
    } 
} 

獲得啓示:How to deserialize dynamic field using Jackson?

+0

處理程序永遠不會被調用。 解串器知道「{」是對象的開始,而不是String:「無法讀取HTTP消息:org.springframework.http.converter.HttpMessageNotReadableExc eption:無法讀取文檔:無法反序列化java實例.lang.String輸出START_OBJECT標記「 –

+0

謝謝。我會考慮1)「無類型」映射和2)自定義解串器 –

+0

不客氣,希望我的回答可以幫助你。如果在slackRequest中沒有很多字段,我建議你使用自定義的反序列化器。所以你可以將它反序列化爲一個字符串或基於eventType的對象。 –