杰克逊无法转换请求元素



我正在使用Spring来制作一个REST API,它公开了一个POST端点。我能够到达终结点,但在读取请求正文时遇到问题。

以下代码有效:payload包含发送的对象。

@RestController
public class RestController {
@RequestMapping(value = "/endpoint")
public ResponseEntity endpoint(@RequestParam("payload") String str) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
Payload payload = objectMapper.readValue(str, Payload.class);
return ResponseEntity.status(HttpStatus.OK).build();
}
}

但是,以下代码不起作用:它会引发异常。

@RestController
public class RestController {
@RequestMapping(value = "/endpoint")
public ResponseEntity endpoint(@RequestParam("payload") Payload payload) throws IOException {
return ResponseEntity.status(HttpStatus.OK).build();
}
}

例外情况:

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

为什么后者不起作用?我认为 Spring 以同样的方式解码请求参数......


更新:我的有效载荷类:

@JsonIgnoreProperties(ignoreUnknown = true)
public class Payload {
@JsonProperty("type")
private String type;
@JsonProperty("callback_id")
private String callbackId;
@JsonProperty("message_ts")
private String message_ts;
@JsonProperty("response_url")
private String responseUrl;
protected Payload() {}
public String getType() {
return type;
}
public String getCallbackId() {
return callbackId;
}
public String getMessage_ts() {
return message_ts;
}
public String getResponseUrl() {
return responseUrl;
}
}

更新:我正在使用邮递员测试端点。这是我发送的内容:

KEY       VALUE
payload   { "type": "test" }

这是我得到的错误:

{
"timestamp": "2018-08-28T10:38:33.133+0000",
"status": 415,
"error": "Unsupported Media Type",
"message": "Content type 'multipart/form-data;boundary=--------------------------586093407866564427326096;charset=UTF-8' not supported",
"path": "/endpoint"
}

不应保护有效负载构造函数。它应该是公开的。

将其更改为

Public PayLoad(){}

否则,控制器无法在映射完成后创建有效负载对象。

使用@RequestBody而不是@RequestParam。您的Payload位于帖子正文中@RequestBody注释会将其反序列化为有效负载。

  1. 摆脱protected Payload() {}.由于您没有任何参数化构造函数,因此Java编译器将负责将默认构造函数添加到编译的字节代码中。

  2. 你需要改变这一点

控制器方法

@RestController
public class RestController {
@RequestMapping(value = "/endpoint")
public ResponseEntity endpoint(@RequestParam("payload") Payload payload) throws IOException {
return ResponseEntity.status(HttpStatus.OK).build();
}
}

变化

a. 更改 HTTP 请求方法以POST它,而不是GET。(method = RequestMethod.POST(。

b. 将有效负载更改为请求参数的消息正文 insteda (@RequestParam("payload") Payload payload-->@RequestBody Payload payload(。

将其更改为

@RequestMapping(value = "/endpoint", method = RequestMethod.POST)
public ResponseEntity endpoint(@RequestBody Payload payload) throws IOException {
return ResponseEntity.status(HttpStatus.OK).build();
}

您的网址模式配置不正确。尝试

@RestController
@RequestMapping(value = "/")
public class PayLoadController {
@RequestMapping(value = "endpoint/",method = RequestMethod.POST)
public ResponseEntity endpoint(@RequestBody Payload payload) throws IOException {
return ResponseEntity.status(HttpStatus.OK).build();
}}

只需复制粘贴此代码并重命名控制器文件名即可。 然后将您的数据发布到 本地主机:8080/端点/

最新更新