使用Spring RestTemplate进行postForObject请求时,如何传递整型请求参数?

3

我在Spring rest服务中有一个方法。

@RequestMapping(value = "test/process", method = RequestMethod.POST)
public @ResponseBody MyResponse processRequest(String RequestId, int count)

我正在使用Spring RestTemplate来调用这个服务,如下:

RestTemplate restTemplate = this.getRestTemplate();
MultiValueMap<String, Object> map = new LinkedMultiValueMap<String, Object>();
map.add("RequestId", RequestId);
map.add("count", count); 
restTemplate.postForObject(url, map,MyResponse.class);

当我尝试调用客户端方法时,出现了异常,提示找不到适合的HttpMessageConverter来处理请求类型[java.lang.Integer]

org.springframework.http.converter.HttpMessageNotWritableException: Could not write request: no suitable HttpMessageConverter found for request type [java.lang.Integer]
at org.springframework.http.converter.FormHttpMessageConverter.writePart(FormHttpMessageConverter.java:310)
at org.springframework.http.converter.FormHttpMessageConverter.writeParts(FormHttpMessageConverter.java:270)
at org.springframework.http.converter.FormHttpMessageConverter.writeMultipart(FormHttpMessageConverter.java:260)
at org.springframework.http.converter.FormHttpMessageConverter.write(FormHttpMessageConverter.java:200)
at org.springframework.http.converter.FormHttpMessageConverter.write(FormHttpMessageConverter.java:1)
at org.springframework.web.client.RestTemplate$HttpEntityRequestCallback.doWithRequest(RestTemplate.java:596)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:444)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:409)
at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:287)

我知道一种方法是将所有参数都传递为字符串。但是以后我可能需要将复杂的数据类型作为参数传递。 有什么办法可以实现这一点。 我已经搜索过了,一些选项似乎是编写自己的转换器。我该如何开始解决这个问题。


在下面这行代码中:map.add("RequestId", RequestId);RequestId是一个比字符串更复杂的对象吗?我们可以看到URL吗?谢谢! - java1337
@java1337 RequestId目前只是一个字符串,但在其他方法中我可能需要提交自定义数据类型或日期对象。 - d123
1个回答

7
这个错误的根本原因在于在LinkedMultiValueMap中指定了一个Integer,这将导致RestTemplate将其视为多部分请求。默认情况下未注册能够处理将Integer类型值写入请求正文的HttpMessageConverter
就像你所说的,你可以通过将count更改为String来解决此问题。毕竟,在HTTP请求参数中没有Integer类型。然而,你还担心:

但是我以后可能需要传递复杂的数据类型作为参数。

假设像这样:
public @ResponseBody MyResponse processRequest(String RequestId, int count, Complex complex) {

使用

public class Complex {
    private String someValue;
    private int intValue;

    public String getSomeValue() {
        return someValue;
    }

    public void setSomeValue(String someValue) {
        this.someValue = someValue;
    }

    public int getIntValue() {
        return intValue;
    }

    public void setIntValue(int intValue) {
        this.intValue = intValue;
    }

    public String toString() {
        return someValue + " " + intValue;
    }
}

以下内容完全可行。
MultiValueMap<String, Object> map = new LinkedMultiValueMap<String, Object>();
map.add("RequestId", "asd");
map.add("count", "42");
map.add("someValue", "complex");
map.add("intValue", "69");
restTemplate.postForObject(url, map,MyResponse.class);

请记住请求参数是通过它们的名称填充模型属性字段的。

更好的解决方案是使用像JSON或XML这样的序列化标准。


谢谢回复。通过“使用像JSON或XML这样的序列化标准。”,你的意思是我应该创建一个请求对象,该对象具有RequestId、count和someValue作为成员,并将该对象提交。控制器应该具有参数RequestBody MyClass myobject。 - d123
@aks 不,我指的是你应该发送 JSON 和 XML 而不是请求参数。Spring 可以通过在处理程序方法参数上使用 @RequestBody 注解来支持这些类型。 - Sotirios Delimanolis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接