简体   繁体   中英

How to return specific object from string during restTemplate.exchange?

My goal is to create a Rest Controller that will return an object (let's call it a Car). This Rest Controller is calling an other Rest API (using a header needed to set a token and be authorized to do the call) to get different data from different endpoint in order to mix them. Like if you ask to Tesla about 2 different car models to create a new crazy Car!

The problem is that this other API is giving me an object which looks like {"Name":"automobile2.0","MotorSize":"v12","Color":"Grey","Weight":"2000kg","Year":"2012"} (actually I receive 28 different fields of different kinds, int, string, array of string, nested json, ... But I only want to keep 3 of them ). And I cannot find a way to convert it to my Car object using RestTemplate and Spring Framework .

Also, if I can find a similar way to receive a List<Car> it will be perfect.

I already tried to use getForObject or getForEntity, unfortunately as I need a header I can't use it.

I was previously doing it by receiving a String and then deserialize it with Genson and a converter, but it didn't not seems to be the best solution.

So now here is my code, first of all, the Car class I want :

public class Car {
  @JsonProperty("Name")
  private String carName;
  @JsonProperty("MotorSize")
  private String motorSize;
  @JsonProperty("Color")
  private String color;
}

And the method I use to do the Rest API call:

public Car getCar() {
  UriComponents uriComponents = 
  UriComponentsBuilder.fromUriString(this.myUrl).build();
  HttpHeaders headers = setHeaders(true);  //a private method which sets the header
  HttpEntity<String> request = new HttpEntity<String>(null, headers); //I don't need a body but I do need a header
  ResponseEntity<Car> response = this.restTemplate.exchange(uriComponents.toUriString(), HttpMethod.GET, request, new ParameterizedTypeReference<Car>() {});
  return response.getBody();
}

I know my call is working because if I do:

ResponseEntity<String> response = this.restTemplate.exchange(uriComponents.toUriString(), HttpMethod.GET, request, String.class);

to replace the response, I get the {"CarName":"automobile2.0","MotorSize":"v12","Color":"Grey"} as response.getBody(), It is what I want but as a String, so wrong format.

What I was expecting to receive from getCar() was a car like:

{
   "carName": "automobile2.0",
   "motorSize": "v12",
   "color": " "grey",
}

Which is next returned by my controller like ResponseEntity<Car>(myCar, HttpStatus.OK)

BUT when I try my controller with Postman, I only receive:

{
   "carName": null,
   "motorSize": null,
   "color": " null,
}

I anyone know how to get my Car from the restTemplate.exchange(...) it will be a great pleasure for me!

Thank you all

您可以尝试添加产品 = MediaType.APPLICATION_JSON_VALUE 并使用 json 格式化程序将您的字符串转换为 JSON。

It may be failing under the cover while converting to Car type because you have unknown properties in you JSON response received from the rest call ie "Weight" and "Year". So first make Jackson understand that you don't care about any other properties then you mentioned in the Car class like so:

@JsonIgnoreProperties(ignoreUnknown = true)
public class Car{

Other than that you don't need to wrap Car in ParameterizedTypeReference you can use it like:

ResponseEntity<Car> response = this.restTemplate.exchange(uriComponents.toUriString(), HttpMethod.GET, request, Car.class);

Wrapping is needed when your object contain generic references which are erased at runtime in this case this is simple class with all types fixed already.

Hope this helps..

刚刚发现问题...由于我们之前使用的是 Genson,JsonProperty 注释仍然是来自 Genson 的注释...所以只需替换 Jackson 的导入即可解决它...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM