ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java-使用Spring解码主体参数

2019-10-25 01:29:08  阅读:314  来源: 互联网

标签:spring-rest slack-api slack spring java


我正在用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) 
{...}

标签:spring-rest,slack-api,slack,spring,java
来源: https://codeday.me/bug/20191025/1925130.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有