我有两个问题:
- 如何使用Spring RestTemplate映射JSON对象列表。
- 如何映射嵌套的JSON对象。
我通过遵循http://spring.io/guides/gs/using-rest/中的教程,尝试使用https://bitpay.com/api/rates。
我有两个问题:
我通过遵循http://spring.io/guides/gs/using-rest/中的教程,尝试使用https://bitpay.com/api/rates。
Answers:
也许这样
ResponseEntity<Object[]> responseEntity = restTemplate.getForEntity(urlGETList, Object[].class);
Object[] objects = responseEntity.getBody();
MediaType contentType = responseEntity.getHeaders().getContentType();
HttpStatus statusCode = responseEntity.getStatusCode();
的控制器代码 RequestMapping
@RequestMapping(value="/Object/getList/", method=RequestMethod.GET)
public @ResponseBody List<Object> findAllObjects() {
List<Object> objects = new ArrayList<Object>();
return objects;
}
ResponseEntity
是对扩展名的HttpEntity
添加HttpStatus
状态代码。使用RestTemplate
以及@Controller
方法。在RestTemplate
此类中,由getForEntity()
和返回exchange()
。
首先定义一个对象来保存实体回到数组中。
@JsonIgnoreProperties(ignoreUnknown = true)
public class Rate {
private String name;
private String code;
private Double rate;
// add getters and setters
}
然后,您可以使用该服务并通过以下方式获取强类型列表:
ResponseEntity<List<Rate>> rateResponse =
restTemplate.exchange("https://bitpay.com/api/rates",
HttpMethod.GET, null, new ParameterizedTypeReference<List<Rate>>() {
});
List<Rate> rates = rateResponse.getBody();
上面的其他解决方案也可以使用,但是我喜欢返回强类型列表而不是Object []。
restTemplate.exchange
封送警官将所有json值映射到匹配的键名时,作为Rate对象中的属性。希望我的想法正确。
对我来说这很有效
Object[] forNow = template.getForObject("URL", Object[].class);
searchList= Arrays.asList(forNow);
对象是您想要的类
Coupon[] coupons = restTemplate.getForObject( url, Coupon[].class)
[]
但完全为空),则可能导致NPE 。因此请小心并检查null
(if (forNow != null)...
)。
Object.class
在方法(method)中指定了什么类型getForObject()
。
经过多次测试,这是我发现的最佳方法:)
Set<User> test = httpService.get(url).toResponseSet(User[].class);
所有你需要的
public <T> Set<T> toResponseSet(Class<T[]> setType) {
HttpEntity<?> body = new HttpEntity<>(objectBody, headers);
ResponseEntity<T[]> response = template.exchange(url, method, body, setType);
return Sets.newHashSet(response.getBody());
}
我这里最大的问题是构建将RestTemplate与兼容的Class匹配所需的Object结构。幸运的是,我找到了http://www.jsonschema2pojo.org/(在浏览器中获取JSON响应并将其用作输入),我对此并不推荐!
我实际上为我的一个项目开发了一些功能,下面是代码:
/**
* @param url is the URI address of the WebService
* @param parameterObject the object where all parameters are passed.
* @param returnType the return type you are expecting. Exemple : someClass.class
*/
public static <T> T getObject(String url, Object parameterObject, Class<T> returnType) {
try {
ResponseEntity<T> res;
ObjectMapper mapper = new ObjectMapper();
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
((SimpleClientHttpRequestFactory) restTemplate.getRequestFactory()).setConnectTimeout(2000);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<T> entity = new HttpEntity<T>((T) parameterObject, headers);
String json = mapper.writeValueAsString(restTemplate.exchange(url, org.springframework.http.HttpMethod.POST, entity, returnType).getBody());
return new Gson().fromJson(json, returnType);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* @param url is the URI address of the WebService
* @param parameterObject the object where all parameters are passed.
* @param returnType the type of the returned object. Must be an array. Exemple : someClass[].class
*/
public static <T> List<T> getListOfObjects(String url, Object parameterObject, Class<T[]> returnType) {
try {
ObjectMapper mapper = new ObjectMapper();
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
((SimpleClientHttpRequestFactory) restTemplate.getRequestFactory()).setConnectTimeout(2000);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<T> entity = new HttpEntity<T>((T) parameterObject, headers);
ResponseEntity<Object[]> results = restTemplate.exchange(url, org.springframework.http.HttpMethod.POST, entity, Object[].class);
String json = mapper.writeValueAsString(results.getBody());
T[] arr = new Gson().fromJson(json, returnType);
return Arrays.asList(arr);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
我希望这会对某人有所帮助!
如果您希望使用“对象列表”,则一种方法是这样的:
public <T> List<T> getApi(final String path, final HttpMethod method) {
final RestTemplate restTemplate = new RestTemplate();
final ResponseEntity<List<T>> response = restTemplate.exchange(
path,
method,
null,
new ParameterizedTypeReference<List<T>>(){});
List<T> list = response.getBody();
return list;
}
并像这样使用它:
List<SomeObject> list = someService.getApi("http://localhost:8080/some/api",HttpMethod.GET);
上面的说明可以在这里(https://www.baeldung.com/spring-rest-template-list)找到,并在下面解释。
“上面的代码中发生了两件事。首先,我们使用ResponseEntity作为返回类型,使用它包装我们真正想要的对象列表。其次,我们调用RestTemplate.exchange()而不是getForObject() 。
这是使用RestTemplate的最通用方法。它要求我们指定HTTP方法,可选的请求正文和响应类型。在这种情况下,我们使用ParameterizedTypeReference的匿名子类作为响应类型。
这最后一部分使我们能够将JSON响应转换为适当类型的对象列表。当我们创建ParameterizedTypeReference的匿名子类时,它使用反射来捕获有关我们要将响应转换为的类类型的信息。
它使用Java的Type对象保留了这些信息,我们不再需要担心类型擦除。”
考虑查看此答案,特别是如果您想在Spring RestTemplate中使用泛型List
以及像List <T>这样的泛型类型ParameterizedTypeReference集合
您可以为每个条目创建POJO,例如,
class BitPay{
private String code;
private String name;
private double rate;
}
然后使用BitPay列表的ParameterizedTypeReference可以用作:
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<List<Employee>> response = restTemplate.exchange(
"https://bitpay.com/api/rates",
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<BitPay>>(){});
List<Employee> employees = response.getBody();
我从这篇文章https://jira.spring.io/browse/SPR-8263找到了解决方法。
根据这篇文章,您可以返回如下类型的列表:
ResponseEntity<? extends ArrayList<User>> responseEntity = restTemplate.getForEntity(restEndPointUrl, (Class<? extends ArrayList<User>>)ArrayList.class, userId);
getForEntity
。还(Class<? extends ArrayList<User>>) ArrayList.class
给出了“不兼容类型”的编译错误。