Spring RestTemplate - 在 GET 中传递对象参数

Spring RestTemplate - Passing in object parameters in GET

如何使用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 class 看起来像这样:

@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 没有正确设置为参数。我该怎么做?

提前致谢。

我猜 这个:

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)

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

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

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

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

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

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

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

You entered 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。