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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 17:15:34  来源:igfitidea点击:

REST client restTemplate can't get Collection of objects

javaspringrestcollectionsresttemplate

提问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 ResponseEntitywith all response information(including status).

你可以使用restTemplate.getForEntity(). 它将向您返回ResponseEntity所有响应信息(包括状态)。

回答by Avi

When you set the Jaxb2RootElementHttpMessageConverteryou override the default converters that comes with RestTemplate. One of the default converters (I think that's the string converter) can handle text/xmltype. Remove the whole Jaxb2RootElementHttpMessageConverterbut leave that part when you expected ArrayList.classand not List.classand 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 acceptheader to choose the use of text/xmland not one of the other produced types:

您可能还需要添加一个accept标题来选择使用text/xml而不是其他生成的类型之一:

List list = template.exchange(URL + "all", new HttpEntity<String>(requestHeaders()), ArrayList.class);

And use exchangewith RestTemplate(instead of getForObject):

并用exchangeRestTemplate(代替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:

它甚至适用于完全通用的设置:

##代码##