【问题标题】:Spring RestTemplate - Passing in object parameters in GETSpring RestTemplate - 在 GET 中传递对象参数
【发布时间】:2016-11-09 06:50:15
【问题描述】:

如何使用 RestTemplate 将对象作为参数传入?例如,假设我使用 Spring Boot 设置了以下服务:

@RequestMapping(value = "/get1", method = RequestMethod.GET)
public ResponseEntity<String> get1(@RequestParam(value = "parm") String parm) {

    String response = "You entered " + parm;
    return new ResponseEntity<String>(response, HttpStatus.OK);
 }

@RequestMapping(value = "/get2", method = RequestMethod.GET)
public ResponseEntity<String> get2(@RequestParam(value = "parm") MyObj parm) {

    String response = "You entered " + parm.getValue();
    return new ResponseEntity<String>(response, HttpStatus.OK);
 }

如果客户想要调用第一个服务,他们可以使用以下方法:

//This works fine
RestTemplate restTemplate = new RestTemplate();
String response = restTemplate.getForObject("http://localhost:8080/get1?parm={parm}", String.class, "Test input 1");

但如果客户想要调用第二个服务,他们会使用以下内容得到 500 错误:

//This doesn't work
MyObj myObj = new MyObj("Test input 2");
RestTemplate restTemplate = new RestTemplate();
String response = restTemplate.getForObject("http://localhost:8080/get2?parm={parm}", String.class, myObj);

MyObj 类如下所示:

@JsonSerialize
public class MyObj {
    private String inputValue;

    public MyObj() {
    }

    public MyObj(String inputValue) {
        this.inputValue = inputValue;
    }

    public String getInputValue() {
        return inputValue;
    }

    public void setInputValue(String inputValue) {
        this.inputValue = inputValue;
    }
}

我假设问题在于 myObj 没有正确设置为参数。我该怎么做?

提前致谢。

【问题讨论】:

    标签: java spring spring-boot get resttemplate


    【解决方案1】:

    我猜 这个:

    String response = restTemplate.getForObject("http://localhost:8080/get2?parm={parm}", String.class, myObj)
    

    应该改变为

    String response = restTemplate.getForObject("http://localhost:8080/get2?parm={parm}", MyObj.class, myObj)
    

    【讨论】:

    • 不,第二个参数(String.class)用于描述响应的返回类型/get1/get2 中的响应都是 String,它是更改的请求参数。
    【解决方案2】:

    当您使用复杂对象(如MyObj)作为@RequestParam 时,Spring 将尝试将字符串转换为该复杂对象。在这种情况下,因为 MyObj 只有一个名为 inputValueString 字段,它会自动使用您提供给查询参数的任何值来填充对象中的属性。

    例如,如果您调用:http://localhost:8080/get2?parm=foobar,您将获得MyObj,其中inputValue 将是"foobar"

    如果您使用RestTemplate,您应该不会收到错误,而是会尝试使用toString() 方法将new MyObj("Test input 2") 转换为字符串,并且响应将是:

    您输入了 com.example.MyObj@63a815e8


    这可能不是你想要的。通常您不想将复杂的对象作为请求参数传递,您可以使用@RequestBodyRequestMethod.POSTrestTemplate.postForEntity() 正确地将您的MyObj 作为JSON 传递。

    像这样改变你的控制器:

    @RequestMapping(value = "/get2", method = RequestMethod.POST)
    public ResponseEntity<String> get2(@RequestBody MyObj parm) {
    
        String response = "You entered " + parm.getInputValue();
        return new ResponseEntity<>(response, HttpStatus.OK);
    }
    

    并像这样使用RestTemplate 调用它:

    MyObj myObj = new MyObj("Test input 2");
    RestTemplate restTemplate = new RestTemplate();
    String response = restTemplate.postForEntity("http://localhost:8080/get2", myObj, String.class).getBody();
    

    这将正确地将您的对象作为 JSON 传递。

    【讨论】:

    • 完美运行。谢谢!
    • 很好的答案!实际上,很多 popele(如果不是每个人 :) )总是将对象编组/解组为 JSON。我总是想知道为什么不在客户端和服务器端都实现接口?只要你不向世界开放你的服务,我相信它完美地使它......
    • @hublo 这就是我在项目中经常做的事情,消费者端的 REST 客户端可以实现与另一端的 REST 服务相同的接口。
    【解决方案3】:

    您必须在responseType 之后传递每个URI 参数的值。问题是RestTemplate 不知道如何将您的对象映射到 URI 参数。您必须显式调用适当的myObj 方法来检索实际值:

    String response = restTemplate.getForObject(
        "http://localhost:8080/get2?parm={parm}", String.class,
        myObj.getInputValue());
    

    您调用的getForObject 方法的签名是: public &lt;T&gt; T getForObject(String url, Class&lt;T&gt; responseType, Object... urlVariables) throws ….

    其中urlVariables 是URI 变量 的数组,用于扩展URI。

    【讨论】:

      猜你喜欢
      • 2012-01-07
      • 1970-01-01
      • 2013-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-14
      相关资源
      最近更新 更多