java-使用Spring解码主体参数

我正在用Spring为Slack应用开发REST API后端.我能够从Slack接收消息(斜杠命令),但是我无法正确接收组件交互(按钮单击).

official documentation说:

Your Action URL will receive a HTTP POST request, including a payload body parameter, itself containing an application/x-www-form-urlencoded JSON string.

因此,我编写了以下@RestController:

@RequestMapping(method = RequestMethod.POST, value = "/actions", headers = {"content-type=application/x-www-form-urlencoded"})
public ResponseEntity action(@RequestParam("payload") ActionController.Action action) {
    return ResponseEntity.status(HttpStatus.OK).build();
}

@JsonIgnoreProperties(ignoreUnknown = true)
class Action {

    @JsonProperty("type")
    private String type;

    public Action() {}

    public String getType() {
        return type;
    }

}

但是我得到以下错误:

Failed to convert request element: org.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException: Failed to convert value of type 'java.lang.String' to required type 'controllers.ActionController$Action'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'controllers.ActionController$Action': no matching editors or conversion strategy found

这是什么意思,如何解决?

解决方法:

您收到包含JSON内容的字符串.您不会收到JSON输入,因为application / x-www-form-urlencoded用作内容类型,而不是如上所述的application / json:

Your Action URL will receive a HTTP POST request, including a payload
body parameter, itself containing an application/x-www-form-urlencoded
JSON string.

因此,将参数类型更改为String并使用Jackson或任何JSON库将String映射到您的Action类:

@RequestMapping(method = RequestMethod.POST, value = "/actions", headers = {"content-type=application/x-www-form-urlencoded"})
public ResponseEntity action(@RequestParam("payload") String actionJSON) {
    Action action = objectMapper.readValue(actionJSON, Action.class);  
    return ResponseEntity.status(HttpStatus.OK).build();
}

正如pvpkiran所建议的那样,如果可以直接在POST请求的主体中传递JSON字符串,而不是将其作为参数值传递,则可以用@RequestBody替换@RequestParam,但事实并非如此.
实际上,通过使用@RequestBody,请求的主体将通过HttpMessageConverter传递,以解析方法参数.

为了回答您的评论,Spring MVC没有提供一种非常简单的方法来满足您的要求:将String JSON映射到Action类.
但是,如果您确实需要自动执行此转换,则可以按照the Spring MVC documentation中的说明使用冗长的替代方法,例如Formatters(强调是我的):

Some annotated controller method arguments that represent String-based
request input — e.g. @RequestParam, @RequestHeader, @PathVariable,
@MatrixVariable, and @CookieValue, may require type conversion if the
argument is declared as something other than String.

For such cases type conversion is automatically applied based on the
configured converters. By default simple types such as int, long,
Date, etc. are supported. Type conversion can be customized through a
WebDataBinder, see DataBinder, or by registering Formatters with the
FormattingConversionService, see Spring Field Formatting.

通过为您的Action类创建一个格式化程序(FormatterRegistry子类),您可以在Spring Web配置as documented中添加该格式化程序:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addFormatters(FormatterRegistry registry) {
        // ... add action formatter here
    }
}

并在您的参数声明中使用它:

public ResponseEntity action(@RequestParam("payload") @Action Action actionJ) 
{...}
上一篇:码农男友用 Python 写了个机器人,租到了让女友满意的房子


下一篇:javascript – 是否可以像在Slack团队中的任何用户一样发布到chat.postMessage?