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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38237217/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 03:14:07  来源:igfitidea点击:

Spring RestTemplate - Passing in object parameters in GET

javaspringspring-bootgetresttemplate

提问by g00glen00b

How do I use the RestTemplate to pass in an object as a parameter? For instance, say that I had the following services set up with Spring Boot:

如何使用 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);
 }

If a client wanted to call the first service, they could use the following:

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

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

But if a client wanted to call the second service, they get a 500 error using the following:

但是如果客户端想要调用第二个服务,他们会使用以下命令收到 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);

The MyObj class looks like this:

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;
    }
}

I'm assuming that the problem is that the myObj is not getting properly setup as a parameter. How do I go about doing this?

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

Thanks in advance.

提前致谢。

回答by g00glen00b

When you're using a complex object (like MyObj) as a @RequestParam, Spring will try to convert a string to that complex object. In this case, because MyObjhas only a single Stringfield called inputValueit will automagically use whatever value you provide to your query parmeter to fill the property in your object.

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

For example, if you call: http://localhost:8080/get2?parm=foobaryou'll get a MyObjwhere inputValuewill be "foobar".

例如,如果你调用:http://localhost:8080/get2?parm=foobar你会得到一个MyObjwhere inputValuewill be "foobar"

If you use RestTemplateyou shouldn't get an error, but in stead it will try to convert new MyObj("Test input 2")to a string, using the toString()method and the response will be:

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

You entered com.example.MyObj@63a815e8

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



This is probably not what you want. Generally you don't want to pass complex objects as request parameters, you can use @RequestBodywith RequestMethod.POSTand restTemplate.postForEntity()to properly pass your MyObjas JSON.

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

Change your controller like this:

像这样改变你的控制器:

@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);
}

And call it using RestTemplatelike this:

RestTemplate像这样调用它:

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

This will properly pass your object as JSON.

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

回答by Michal Foksa

You have to pass value of each URI parameter after responseType. Problem is that RestTemplatedoes not know how to map your object to URI parameters. You have to explicitly call appropriate myObjmethod to retrieve the actual value:

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

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

Signature of the getForObjectmethod you call is: public <T> T getForObject(String url, Class<T> responseType, Object... urlVariables) throws ….

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

where urlVariablesis array of URI variable valuesto expand the URI with.

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

回答by IZI_SL

i'm guessing this:

我猜这个:

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

should change as

应该改变为

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