我尝试使用 Spring Boot 3 Http RestClient 发送 POST 请求。发送和反对时请求失败,发送字符串时请求通过。
适用于字符串代码:
private final String roleBody = """
{"ApplicationID":"XXXX","RolesValues":["ROLE"],"retainPreviousRoles":"true"}
""";
ResponseEntity<ApiResponse> result = restClient
.post()
.uri("dev/v1/app-roles")
.accept(APPLICATION_JSON)
.contentType(APPLICATION_JSON)
.body(addAppRole)
.body(roleBody)
.retrieve()
.toEntity(ApiResponse.class);
调试打开 http 客户端日志记录的输出:
User-Agent: Apache-HttpClient/5.2.3 (Java/17.0.11)
"POST /dev/v1/app-roles HTTP/1.1[\r][\n]"
"Content-Type: application/json[\r][\n]"
"Accept: application/json[\r][\n]"
"Accept-Encoding: gzip, x-gzip, deflate[\r][\n]"
"Content-Length: 128[\r][\n]"
"Host: appregapi.bpglobal.com[\r][\n]"
"Connection: keep-alive[\r][\n]"
"User-Agent: Apache-HttpClient/5.2.3 (Java/17.0.11)[\r][\n]"
"[\r][\n]"
"{"ApplicationID":"XXXX","RolesValues":["ROLE"],"retainPreviousRoles":"true"}[\n]"
"HTTP/1.1 200 OK[\r][\n]"
"Transfer-Encoding: chunked[\r][\n]"
"Content-Type: application/json; charset=utf-8[\r][\n]"
"Content-Encoding: gzip[\r][\n]"
"Vary: Accept-Encoding[\r][\n]"
"Date: Sat, 08 Jun 2024 20:22:09 GMT[\r][\n]"
"[\r][\n]"
"44[\r][\n]"
当目标代码失败时:
AddAppRole addAppRole = AddAppRole.builder()
.applicationId("XXXX")
.rolesValues(List.of("ROLE"))
.retainPreviousRoles("true")
.build();
ResponseEntity<ApiResponse> result = restClient
.post()
.uri("dev/v1/app-roles")
.accept(APPLICATION_JSON)
.contentType(APPLICATION_JSON)
.body(addAppRole)
.retrieve()
.toEntity(ApiResponse.class);
调试打开 http 客户端日志记录的输出:
User-Agent: Apache-HttpClient/5.2.3 (Java/17.0.11)
"POST /dev/v1/app-roles HTTP/1.1[\r][\n]"
"Content-Type: application/json[\r][\n]"
"Accept: application/json[\r][\n]"
"Accept-Encoding: gzip, x-gzip, deflate[\r][\n]"
"Transfer-Encoding: chunked[\r][\n]"
"Host: appregapi.bpglobal.com[\r][\n]"
"Connection: keep-alive[\r][\n]"
"User-Agent: Apache-HttpClient/5.2.3 (Java/17.0.11)[\r][\n]"
"[\r][\n]"
"7f[\r][\n]"
"{"ApplicationID":"XXXX","RolesValues":["ROLE"],"retainPreviousRoles":"true"}[\r][\n]"
"0[\r][\n]"
"[\r][\n]"
"HTTP/1.1 403 Forbidden[\r][\n]"
"Transfer-Encoding: chunked[\r][\n]"
"Content-Type: application/json; charset=utf-8[\r][\n]"
"Date: Sat, 08 Jun 2024 20:23:35 GMT[\r][\n]"
"[\r][\n]"
"46[\r][\n]"
"{[\r][\n]"
HTTP/1.1 403 Forbidden
有效负载出现差异?
知道为什么第二个版本要添加: 7f 和 0
不同的编码破坏了请求。
您介意分享您的 AddAppRole 类吗?
问题似乎源于两种不同方法中正文的序列化和传输方式。当您直接发送 JSON 字符串时,它会按原样传输,而当您发送对象时,它会由 Spring Boot RestClient 序列化。您看到的额外字符 (7f 和 0 ) 表示分块传输编码,这是一种分块发送数据的方式,通常在事先未知内容长度时使用。
要解决这个问题,您可以尝试以下几种方法:
确保正确的序列化: 验证您的 AddAppRole 类是否已正确序列化为 JSON。确保 AddAppRole 中的所有字段与预期的 JSON 键完全匹配。如果正确的字段名称与类字段名称不同,您可能需要使用 Jackson 注释来指定正确的字段名称。
导入 com.fasterxml.jackson.annotation.JsonProperty;
public class AddAppRole {
@JsonProperty("ApplicationID")
private String applicationId;
@JsonProperty("RolesValues")
private List<String> rolesValues;
@JsonProperty("retainPreviousRoles")
private String retainPreviousRoles;
}
如果问题仍然存在,您可以手动将对象转换为 JSON 并将其作为字符串发送,确保正文格式保持一致:
ObjectMapper objectMapper = new ObjectMapper();
String roleBody = objectMapper.writeValueAsString(addAppRole);
ResponseEntity<ApiResponse> result = restClient
.post()
.uri("dev/v1/app-roles")
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(roleBody))
.retrieve()
.toEntity(ApiResponse.class)
.block();