我正在使用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
注释会将其反序列化为有效负载。
-
摆脱
protected Payload() {}
.由于您没有任何参数化构造函数,因此Java编译器将负责将默认构造函数添加到编译的字节代码中。 -
你需要改变这一点
控制器方法
@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/端点/