没有@RequestBody的Spring @RequestMapping方法

时间:2017-10-06 17:19:39

标签: spring spring-boot slack-api

在Spring Boot Controller方法中,如何获取POST的正文?我见过的所有例子都使用了@RequestBody。如何在不使用@RequestBody的情况下获取身体?

我正在编写一个处理Slack Events的方法。当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;

并将其Setter方法定义为

@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;
    }
}

1 个答案:

答案 0 :(得分: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?

获取灵感