user6448130
user6448130

Reputation:

Spring RestTemplate - Passing in object parameters in GET

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:

@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:

//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:

@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?

Thanks in advance.

Upvotes: 2

Views: 20713

Answers (3)

IZI_SL
IZI_SL

Reputation: 183

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)

Upvotes: -2

Dimitri Mestdagh
Dimitri Mestdagh

Reputation: 44665

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 MyObj has only a single String field called inputValue it will automagically use whatever value you provide to your query parmeter to fill the property in your object.

For example, if you call: http://localhost:8080/get2?parm=foobar you'll get a MyObj where inputValue will be "foobar".

If you use RestTemplate you 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:

You entered 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 @RequestBody with RequestMethod.POST and restTemplate.postForEntity() to properly pass your MyObj as 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 RestTemplate like this:

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.

Upvotes: 4

Michal Foksa
Michal Foksa

Reputation: 12024

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

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

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

where urlVariables is array of URI variable values to expand the URI with.

Upvotes: 0

Related Questions