我有一个形式的POJO:
@Data
public class BaseRequest {
private String type;
private Map<String, Object> details;
private Map<String, Object> signature;
}
我的服务运行只接受内容类型:&#34; application / x-www-form-urlencoded&#34;。
我用Java编写了一个客户端,使用Spring的RestTemplate进行调用。
public String getInvoice(BaseRequest req, String url) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<BaseRequest> httpEntity = new HttpEntity<BaseRequest>(req, headers);
String response = this.restTemplate.postForObject(url, httpEntity, String.class);
return response;
}
但是,它会抛出错误:
org.springframework.web.client.RestClientException: Could not write request: no suitable HttpMessageConverter found for request type [com.x.y.z.BaseRequest] and content type [application/x-www-form-urlencoded]
如果我将内容类型设置为JSON:
headers.setContentType(MediaType.APPLICATION_JSON);
我知道它适用于JSON,因为我已经使用JacksonHTTPMessageConverter配置了我的RestTemplate Bean。所以我可以轻松地将POJO转换为application / json。但是,我无法弄清楚如何使用application / x-www-form-urlencoded来做到这一点。
我现在已经搜索了一段时间了,我找到的唯一解决方案是编写自己的转换器将我的BaseRequest类转换为Spring的MultiValueMap,然后是Spring&#39 ; s FormHttpMessageConverter将自动处理它。但我想避免这样做。还有其他方法吗?
任何线索都会受到赞赏。谢谢!
编辑: 我的问题与@JsonProperty not working for Content-Type : application/x-www-form-urlencoded不同。在那里发生的转换是关于在application / x-www-form-urlencoded中接受数据并将其转换为POJO。我的问题是在使用Spring的resttemplate进行调用时将POJO转换为application / x-www-form-urlencoded。就像我提到的那样,我知道我可以通过编写自己的转换器将我的POJO转换为Spring的MultiValueMap来实现这一目标。但是,我想知道我是否可以避免这样做。
编辑:
Dump of $_POST on the API when I send my data as MultiValueMap<String, Object>:
"array(0) {
}"
Dump of $_POST on the API when I send my data through Postman in the correct format:
"array(2) {
["type"]=>
string(16) "abcd"
["details"]=>
array(1) {
["template_file"]=>
string(16) "x.html"
}
}"
答案 0 :(得分:0)
尝试将请求有效负载中的嵌套对象转换为org.springframework.util.MultiValueMap
。在POJO中添加并实现转换器方法
public class BaseRequest {
// ...
public MultiValueMap<String, Object> toMap() {
MultiValueMap<String, Object> result = new LinkedMultiValueMap<>();
result.add("type", type);
result.put("details", details);
result.put("signature", signature);
return result;
}
}
现在在请求创建期间使用它
HttpEntity<BaseRequest> httpEntity = new HttpEntity<BaseRequest>(req.toMap(), headers);
这是因为在FormHttpMessageConverter
内执行实际转化方法canRead(Class<?>, MediaType)
检查MultiValueMap.class.isAssignableFrom(clazz)
clazz是否为您的有效负载对象。在你的情况下它失败了,所以FormHttpMessageConverter
被跳过了。
希望它有所帮助!