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
只有一个名为 inputValue
的 String
字段,它将自动使用您提供给查询参数的任何值来填充对象中的 属性。
例如,如果您调用:http://localhost:8080/get2?parm=foobar
,您将得到一个 MyObj
,其中 inputValue
将是 "foobar"
。
如果你使用 RestTemplate
你不应该得到一个错误,而是它会尝试使用 toString()
方法将 new MyObj("Test input 2")
转换为一个字符串,并且响应将是:
You entered com.example.MyObj@63a815e8
这可能不是您想要的。通常您不想将复杂的对象作为请求参数传递,您可以将 @RequestBody
与 RequestMethod.POST
和 restTemplate.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。
如何使用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
只有一个名为 inputValue
的 String
字段,它将自动使用您提供给查询参数的任何值来填充对象中的 属性。
例如,如果您调用:http://localhost:8080/get2?parm=foobar
,您将得到一个 MyObj
,其中 inputValue
将是 "foobar"
。
如果你使用 RestTemplate
你不应该得到一个错误,而是它会尝试使用 toString()
方法将 new MyObj("Test input 2")
转换为一个字符串,并且响应将是:
You entered com.example.MyObj@63a815e8
这可能不是您想要的。通常您不想将复杂的对象作为请求参数传递,您可以将 @RequestBody
与 RequestMethod.POST
和 restTemplate.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。