web-dev-qa-db-fra.com

POST demande via RestTemplate en JSON

Je n'ai trouvé aucun exemple pour résoudre mon problème, alors je veux vous demander de l'aide. Je ne peux pas simplement envoyer une demande POST à l'aide d'un objet RestTemplate dans JSON

A chaque fois que je reçois:

org.springframework.web.client.HttpClientErrorException: 415 Type de média non pris en charge

J'utilise RestTemplate de cette manière:

...
restTemplate = new RestTemplate();
List<HttpMessageConverter<?>> list = new ArrayList<HttpMessageConverter<?>>();
list.add(new MappingJacksonHttpMessageConverter());
restTemplate.setMessageConverters(list);
...
Payment payment= new Payment("Aa4bhs");
Payment res = restTemplate.postForObject("http://localhost:8080/aurest/rest/payment", payment, Payment.class);

Quelle est ma faute?

113
Johnny B

Cette technique a fonctionné pour moi:

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

HttpEntity<String> entity = new HttpEntity<String>(requestJson, headers);
ResponseEntity<String> response = restTemplate.put(url, entity);

J'espère que ça aide

151
kanu dialani

J'ai rencontré ce problème lors de la tentative de débogage d'un noeud final REST. Voici un exemple de base utilisant la classe RestTemplate de Spring pour effectuer une demande POST que j'ai utilisée. Il m'a fallu beaucoup de temps pour reconstituer le code de différents endroits pour obtenir une version fonctionnelle.

RestTemplate restTemplate = new RestTemplate();

String url = "endpoint url";
String requestJson = "{\"queriedQuestion\":\"Is there pain in your hand?\"}";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

HttpEntity<String> entity = new HttpEntity<String>(requestJson,headers);
String answer = restTemplate.postForObject(url, entity, String.class);
System.out.println(answer);

L'analyseur JSON particulier de mon noeud final repos utilisait les guillemets nécessaires autour des noms de champs, c'est pourquoi j'ai échappé à ces guillemets dans ma chaîne requestJson.

88
Morgan Kenyon

J'utilise un modèle de repos avec JSONObjects comme suit:

// create request body
JSONObject request = new JSONObject();
request.put("username", name);
request.put("password", password);

// set headers
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<String>(request.toString(), headers);

// send request and parse result
ResponseEntity<String> loginResponse = restTemplate
  .exchange(urlString, HttpMethod.POST, entity, String.class);
if (loginResponse.getStatusCode() == HttpStatus.OK) {
  JSONObject userJson = new JSONObject(loginResponse.getBody());
} else if (loginResponse.getStatusCode() == HttpStatus.UNAUTHORIZED) {
  // nono... bad credentials
}
69
Mikael Lepistö

Comme spécifié ici Je suppose que vous devez ajouter un messageConverter pour MappingJacksonHttpMessageConverter

13
Raghuram

Si vous utilisez Spring 3.0, un moyen facile d'éviter l'exception org.springframework.web.client.HttpClientErrorException: 415 type de support non pris en charge consiste à inclure les fichiers jar jackson dans votre classpath et utilisez l’élément mvc:annotation-driven config. Comme spécifié ici .

Je tirais mes cheveux en essayant de comprendre pourquoi l'application mvc-ajax fonctionnait sans aucune configuration spéciale pour la MappingJacksonHttpMessageConverter. Si vous lisez l'article que j'ai lié ci-dessus de près:

Sous les capots, Spring MVC délègue à un HttpMessageConverter pour effectuer la sérialisation. Dans ce cas, Spring MVC appelle un convertisseur MappingJacksonHttpMessageConverter construit sur le processeur JSON de Jackson. Cette implémentation est activée automatiquement lorsque vous utilisez l'élément de configuration piloté par annotation mvc: avec la présence de Jackson dans votre chemin de classe .

8
Mike G

L'erreur "415 Type de support non pris en charge" vous indique que le serveur n'acceptera pas votre demande POST. Votre demande est absolument correcte, c'est le serveur qui est mal configuré.

MappingJacksonHttpMessageConverter définira automatiquement l'en-tête de type de contenu de la demande sur application/json, et je suppose que votre serveur le refuse. Cependant, vous ne nous avez rien dit à propos de la configuration de votre serveur. Je ne peux donc pas vous conseiller à ce sujet.

7
skaffman

Je fais de cette façon et ça marche.

HttpHeaders headers = createHttpHeaders(map);
public HttpHeaders createHttpHeaders(Map<String, String> map)
{   
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    for (Entry<String, String> entry : map.entrySet()) {
        headers.add(entry.getKey(),entry.getValue());
    }
    return headers;
}

// passe les en-têtes ici

 String requestJson = "{ // Construct your JSON here }";
logger.info("Request JSON ="+requestJson);
HttpEntity<String> entity = new HttpEntity<String>(requestJson, headers);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
logger.info("Result - status ("+ response.getStatusCode() + ") has body: " + response.hasBody());
logger.info("Response ="+response.getBody());

J'espère que cela t'aides

6
Yakhoob

J'avais ce problème et j'utilise RestTemplate de Spring sur le client et Spring Web sur le serveur. Les deux rapports d'erreurs sont très médiocres pour les deux API, ce qui les rend extrêmement difficiles à développer.

Après de nombreuses heures d’essais de toutes sortes d’expériences, j’ai réalisé que le problème était causé par la transmission d’une référence nulle pour le corps POST à la place de la liste attendue. Je présume que RestTemplate ne peut pas déterminer le type de contenu à partir d'un objet null, mais ne s'en plaint pas. Après avoir ajouté les en-têtes appropriés, j'ai commencé à obtenir une autre exception côté serveur dans Spring avant d'entrer dans ma méthode de service.

Le correctif consistait à transmettre une liste vide du client au lieu de null. Aucun en-tête n'est requis car le type de contenu par défaut est utilisé pour les objets non nuls.

4
Alex Worden

Ce code fonctionne pour moi;

RestTemplate restTemplate = new RestTemplate();
Payment payment = new Payment("Aa4bhs");
MultiValueMap<String, Object> map = new LinkedMultiValueMap<String, Object>();
map.add("payment", payment);
HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<MultiValueMap<String, Object>>(map, headerObject);

Payment res = restTemplate.postForObject(url, httpEntity, Payment.class);
3
Ganesh

Si vous ne voulez pas traiter la réponse

private RestTemplate restTemplate = new RestTemplate();
restTemplate.postForObject(serviceURL, request, Void.class);

Si vous avez besoin d'une réponse pour traiter

String result = restTemplate.postForObject(url, entity, String.class);
2
Vipindas Gopalan

Pour moi une erreur est survenue avec cette configuration:

AndroidAnnotationsSpring Android RestTemplate Module et ...

GsonHttpMessageConverter

Les annotations Android ont quelques problèmes avec cette conversion pour générer une demande POST sans paramètre. Il suffit de paramétrer new Object() pour le résoudre.

0

Pourquoi travailler plus fort que nécessaire? postForEntity accepte un objet Map simple en entrée. Ce qui suit fonctionne bien pour moi lors de l'écriture de tests pour un noeud final donné REST au printemps. Je pense que c'est la manière la plus simple de faire une demande JSON POST au printemps:

@Test
public void shouldLoginSuccessfully() {
  // 'restTemplate' below has been @Autowired prior to this
  Map map = new HashMap<String, String>();
  map.put("username", "bob123");
  map.put("password", "myP@ssw0rd");
  ResponseEntity<Void> resp = restTemplate.postForEntity(
      "http://localhost:8000/login",
      map,
      Void.class);
  assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.OK);
}
0
eriegz