Java REST 客户端 restTemplate 无法获取对象的集合
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19449256/
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
REST client restTemplate can't get Collection of objects
提问by Oleksandr H
I use Spring restTemplate. I made a REST service and client as unit test in separated application. I have method that return List of users and method for user creating:
我使用 Spring restTemplate。我在单独的应用程序中制作了一个 REST 服务和客户端作为单元测试。我有返回用户列表和用户创建方法的方法:
@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON,
MediaType.TEXT_XML })
@Path("/all")
public Response getAllUsers() {
List<User> list = dao.getAll();
GenericEntity<List<User>> result = new GenericEntity<List<User>>(list) {
};
return Response.status(Status.OK).entity(result).build();
}
If I request to show me all users in browser, it displays to me xml. It's OK. But, when I try to use this:
如果我请求在浏览器中向我显示所有用户,它会向我显示 xml。没关系。但是,当我尝试使用它时:
@Test
public void testGetAll() {
List list = new RestTemplate().getForObject(URL + "all", List.class);
System.out.println(list);
}
I got
我有
WARNING: GET request for "http://localhost:8080/REST/all" resulted in 500 (Internal Server Error); invoking error handler
I tried to debug this. No exceptions during method works. And browser shows me the xml with users. What can be wrong?
我试图调试这个。在方法工作期间没有例外。浏览器向我展示了用户的 xml。有什么问题?
Also, I want to know, how I can get status code or message from template object (for test)?
另外,我想知道,如何从模板对象(用于测试)获取状态代码或消息?
Thanks for your answers.
感谢您的回答。
EDITED:
编辑:
I modified my test method:
我修改了我的测试方法:
@Test
public void testGetAll() {
RestTemplate template = new RestTemplate();
List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
Jaxb2RootElementHttpMessageConverter jaxbMessageConverter = new Jaxb2RootElementHttpMessageConverter();
List<MediaType> mediaTypes = new ArrayList<MediaType>();
mediaTypes.add(MediaType.APPLICATION_XML);
jaxbMessageConverter.setSupportedMediaTypes(mediaTypes);
messageConverters.add(jaxbMessageConverter);
template.setMessageConverters(messageConverters);
List list = template.getForObject(URL + "all",
ArrayList.class);
System.out.println(list);
}
And I got exception:
我有例外:
org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [class java.util.ArrayList] and content type [application/xml]
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:107)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:496)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:452)
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:222)
at com.nixsolutions.web.service.rest.UserRESTServiceTest.testGetAll(UserRESTServiceTest.java:61)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access@Test
public void testGetAll() {
RestTemplate template = new RestTemplate();
List list = template.getForObject(URL + "all",
ArrayList.class);
System.out.println(list);
}
0(ParentRunner.java:53)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
回答by Admit
You could use restTemplate.getForEntity()
. It will return you ResponseEntity
with all response information(including status).
你可以使用restTemplate.getForEntity()
. 它将向您返回ResponseEntity
所有响应信息(包括状态)。
回答by Avi
When you set the Jaxb2RootElementHttpMessageConverter
you override the default converters that comes with RestTemplate
. One of the default converters (I think that's the string converter) can handle text/xml
type. Remove the whole Jaxb2RootElementHttpMessageConverter
but leave that part when you expected ArrayList.class
and not List.class
and this will work:
当您设置 时,Jaxb2RootElementHttpMessageConverter
您会覆盖RestTemplate
. 默认转换器之一(我认为是字符串转换器)可以处理text/xml
类型。删除整个Jaxb2RootElementHttpMessageConverter
但在您期望的时候保留该部分ArrayList.class
而不是List.class
,这将起作用:
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setAccept(Arrays.asList(new MediaType[] {MediaType.TEXT_XML}));
You might also need to add an accept
header to choose the use of text/xml
and not one of the other produced types:
您可能还需要添加一个accept
标题来选择使用text/xml
而不是其他生成的类型之一:
List list = template.exchange(URL + "all", new HttpEntity<String>(requestHeaders()), ArrayList.class);
And use exchange
with RestTemplate
(instead of getForObject
):
并用exchange
与RestTemplate
(代替getForObject
):
RestTemplate template = new RestTemplate(true);
ResponseEntity<TblGps[]> responseEntity = restTemplate.getForEntity(urlGETList, TblGps[].class);
TblGps[]=responseEntity.getBody();
回答by kamokaze
maybe this way ....
也许这样......
ResponseEntity<? extends ArrayList<User>> responseEntity = restTemplate.getForEntity(restEndPointUrl, (Class<? extends ArrayList<User>>)ArrayList.class, userId);
回答by chrismarx
You need to use a concrete implementation of List
, for instance you can use ArrayList
, see this example:
您需要使用 的具体实现List
,例如您可以使用ArrayList
,请参阅此示例:
ResponseEntity<? extends ArrayList<HashMap<String,Object>>> responseEntity = restTemplate.getForEntity(restEndPointUrl, (Class<? extends ArrayList<HashMap<String,Object>>>)ArrayList.class, parameterId);
it even works for an entirely generic setup:
它甚至适用于完全通用的设置:
##代码##