J'utilise Spring restTemplate. J'ai créé un service et un client REST en tant que test unitaire dans une application séparée. J'ai la méthode qui retourne la liste des utilisateurs et la méthode pour créer un utilisateur:
@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();
}
Si je demande à me montrer tous les utilisateurs dans le navigateur, il m'affiche xml. C'est bon. Mais, quand j'essaye d'utiliser ceci:
@Test
public void testGetAll() {
List list = new RestTemplate().getForObject(URL + "all", List.class);
System.out.println(list);
}
J'ai eu
WARNING: GET request for "http://localhost:8080/REST/all" resulted in 500 (Internal Server Error); invoking error handler
J'ai essayé de déboguer ceci. Aucune exception pendant les travaux de méthode. Et le navigateur me montre le xml avec les utilisateurs . Quel est le problème?
En outre, je veux savoir comment je peux obtenir un code d'état ou un message à partir d'un objet modèle (pour le test)?
Merci pour vos réponses.
ÉDITÉ:
J'ai modifié ma méthode de test:
@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);
}
Et j'ai eu une 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$1.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$3.run(ParentRunner.Java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.Java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.Java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.Java:53)
at org.junit.runners.ParentRunner$2.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)
peut-être de cette façon ....
RestTemplate template = new RestTemplate(true);
ResponseEntity<TblGps[]> responseEntity = restTemplate.getForEntity(urlGETList, TblGps[].class);
TblGps[]=responseEntity.getBody();
Vous devez utiliser une implémentation concrète de List
. Par exemple, vous pouvez utiliser ArrayList
. Voir cet exemple:
ResponseEntity<? extends ArrayList<User>> responseEntity = restTemplate.getForEntity(restEndPointUrl, (Class<? extends ArrayList<User>>)ArrayList.class, userId);
cela fonctionne même pour une configuration entièrement générique:
ResponseEntity<? extends ArrayList<HashMap<String,Object>>> responseEntity = restTemplate.getForEntity(restEndPointUrl, (Class<? extends ArrayList<HashMap<String,Object>>>)ArrayList.class, parameterId);
Lorsque vous définissez le Jaxb2RootElementHttpMessageConverter
, vous remplacez les convertisseurs par défaut fournis avec RestTemplate
. L'un des convertisseurs par défaut (je pense que c'est le convertisseur de chaîne) peut gérer le type text/xml
. Supprimez le Jaxb2RootElementHttpMessageConverter
entier mais laissez cette partie lorsque vous attendez ArrayList.class
et non pas List.class
et ceci fonctionnera:
@Test
public void testGetAll() {
RestTemplate template = new RestTemplate();
List list = template.getForObject(URL + "all",
ArrayList.class);
System.out.println(list);
}
Vous devrez peut-être également ajouter un en-tête accept
pour choisir l’utilisation de text/xml
et non l’un des autres types produits:
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setAccept(Arrays.asList(new MediaType[] {MediaType.TEXT_XML}));
Et utilisez exchange
avec RestTemplate
(au lieu de getForObject
):
List list = template.exchange(URL + "all", new HttpEntity<String>(requestHeaders()), ArrayList.class);
Vous pouvez utiliser restTemplate.getForEntity()
. Il vous renverra ResponseEntity
avec toutes les informations de réponse (y compris le statut).