Comment POSTER des données de formulaire avec Spring RestTemplate?


149

Je souhaite convertir l'extrait de code curl suivant (fonctionnel) en un appel RestTemplate:

curl -i -X POST -d "email=first.last@example.com" https://app.example.com/hr/email

Comment transmettre correctement le paramètre email? Le code suivant entraîne une réponse 404 non trouvée:

String url = "https://app.example.com/hr/email";

Map<String, String> params = new HashMap<String, String>();
params.put("email", "first.last@example.com");

RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.postForEntity( url, params, String.class );

J'ai essayé de formuler l'appel correct dans PostMan, et je peux le faire fonctionner correctement en spécifiant le paramètre email comme paramètre "form-data" dans le corps. Quelle est la bonne façon d'obtenir cette fonctionnalité dans un RestTemplate?


Essayez restTemplate.exchange ();
— Nous sommes Borg le

Quel est le type de contenu acceptable de l'URL que vous avez fournie ici?
— Tharsan Sivakumar

Regardez ce blog qui essaie de faire la même chose que je suppose techie-mixture.blogspot.com/2016/07
— ...

@TharsanSivakumar L'URL renverra JSON.
— sim

Possible duplicata de RestTemplate uriVariables not
— extended

Réponses:


357

La méthode POST doit être envoyée avec l'objet de requête HTTP. Et la demande peut contenir un en-tête HTTP ou un corps HTTP ou les deux.

Créons donc une entité HTTP et envoyons les en-têtes et les paramètres dans le corps.

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

MultiValueMap<String, String> map= new LinkedMultiValueMap<String, String>();
map.add("email", "first.last@example.com");

HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);

ResponseEntity<String> response = restTemplate.postForEntity( url, request , String.class );

http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html#postForObject-java.lang.String-java.lang.Object-java.lang. Classe-java.lang.Object ...-


1
Vous pouvez également consulter ce lien pour plus d'informations techie-mixture.blogspot.com/2016/07/…
— Tharsan Sivakumar

1
Vous avez sauvé ma journée, je m'attendais à ce que l'utilisation de resttemplate soit assez évidente, mais il y a quelques astuces!
— Sergii Getman

1
ResponseEntity<String> response = new RestTemplate().postForEntity(url, request, String.class);Je reçoisorg.springframework.http.converter.HttpMessageNotWritableExc‌​eption: Could not write content: No serializer found for class java.util.Collections$3
— Shivkumar Mallesappa

Comment passer le paramètre du corps lorsque d'autres sont des chaînes mais que l'une d'entre elles est de type String [], comme ci-dessous, les données de requête argssont un tableau de Stringcurl -X POST --data '{"file": "/xyz.jar", "className": "my.class.name", "args": ["100"]}' -H "Content-Type: application/json" localhost:1234/batches
— khawarizmi

2
Donc, cela ne fonctionne que pour les chaînes ... Que faire si je veux envoyer un objet java dans la charge utile?
— devssh

23

Comment POSTER des données mixtes: fichier, chaîne [], chaîne en une seule requête.

Vous ne pouvez utiliser que ce dont vous avez besoin.

private String doPOST(File file, String[] array, String name) {
    RestTemplate restTemplate = new RestTemplate(true);

    //add file
    LinkedMultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
    params.add("file", new FileSystemResource(file));

    //add array
    UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("https://my_url");
    for (String item : array) {
        builder.queryParam("array", item);
    }

    //add some String
    builder.queryParam("name", name);

    //another staff
    String result = "";
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.MULTIPART_FORM_DATA);

    HttpEntity<LinkedMultiValueMap<String, Object>> requestEntity =
            new HttpEntity<>(params, headers);

    ResponseEntity<String> responseEntity = restTemplate.exchange(
            builder.build().encode().toUri(),
            HttpMethod.POST,
            requestEntity,
            String.class);

    HttpStatus statusCode = responseEntity.getStatusCode();
    if (statusCode == HttpStatus.ACCEPTED) {
        result = responseEntity.getBody();
    }
    return result;
}

La requête POST aura File dans son corps et sa structure suivante:

POST https://my_url?array=your_value1&array=your_value2&name=bob 

J'ai essayé cette méthode mais je n'ai pas fonctionné pour moi. Je suis confronté à un problème lors d'une demande POST avec les données au format multipart. Voici ma question si vous pouviez me guider avec une solution stackoverflow.com/questions/54429549/…
— Deep Lathia

8

voici le programme complet pour effectuer un appel de repos POST en utilisant RestTemplate de spring.

import java.util.HashMap;
import java.util.Map;

import org.springframework.http.HttpEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import com.ituple.common.dto.ServiceResponse;

   public class PostRequestMain {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
        Map map = new HashMap<String, String>();
        map.put("Content-Type", "application/json");

        headers.setAll(map);

        Map req_payload = new HashMap();
        req_payload.put("name", "piyush");

        HttpEntity<?> request = new HttpEntity<>(req_payload, headers);
        String url = "http://localhost:8080/xxx/xxx/";

        ResponseEntity<?> response = new RestTemplate().postForEntity(url, request, String.class);
        ServiceResponse entityResponse = (ServiceResponse) response.getBody();
        System.out.println(entityResponse.getData());
    }

}

7
Cela publie application / json au lieu de données de formulaire
— Maciej Stępyra

ResponseEntity<?> response = new RestTemplate().postForEntity(url, request, String.class);. Je reçoisorg.springframework.http.converter.HttpMessageNotWritableException: Could not write content: No serializer found for class java.util.Collections$3
— Shivkumar Mallesappa

pourriez-vous s'il vous plaît partager votre programme entier ou laissez-moi savoir que je vais partager un exemple de programme @ShivkumarMallesappa
— Piyush Mittal

Si vous remplacez le application/jsontype de contenu par le, application/x-www-form-urlencodedvous obtiendrez org.springframework.web.client.RestClientException: Non HttpMessageConverter pour java.util.HashMap et le type de contenu "application / x-www-form-urlencoded" - voir stackoverflow.com/q / 31342841/355438
— Lu55

-3

Votre chaîne d'URL a besoin de marqueurs variables pour la carte que vous transmettez au travail, comme:

String url = "https://app.example.com/hr/email?{email}";

Ou vous pouvez coder explicitement les paramètres de requête dans la chaîne pour commencer et ne pas avoir à passer du tout la carte, comme:

String url = "https://app.example.com/hr/email?email=first.last@example.com";

Voir également https://stackoverflow.com/a/47045624/1357094

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.