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 protected]" 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", "[email protected]");

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?

sim
la source
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", "[email protected]");

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 ...-

Tharsan Sivakumar
la source
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 
Yuliia Ashomok
la source
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());
    }

}
Piyush Mittal
la source
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 protected]";

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

cellepo
la source