Wie poste ich Formulardaten mit Spring RestTemplate?


146

Ich möchte das folgende (funktionierende) Curl-Snippet in einen RestTemplate-Aufruf konvertieren:

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

Wie übergebe ich den E-Mail-Parameter korrekt? Der folgende Code führt zu einer Antwort 404 Not Found:

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 );

Ich habe versucht, den richtigen Aufruf in PostMan zu formulieren, und ich kann ihn korrekt zum Laufen bringen, indem ich den E-Mail-Parameter als "Formulardaten" -Parameter im Textkörper spezifiziere. Was ist der richtige Weg, um diese Funktionalität in einem RestTemplate zu erreichen?


Versuchen Sie restTemplate.exchange ();
Wir sind Borg

Was ist der akzeptable Inhaltstyp der URL, die Sie hier angegeben haben?
Tharsan Sivakumar

Schauen Sie sich diesen Blog an, der versucht, das Gleiche zu tun, denke ich techie-mixture.blogspot.com/2016/07/…
Tharsan Sivakumar

@TharsanSivakumar Die URL gibt JSON zurück.
Sim

Antworten:


355

Die POST-Methode sollte entlang des HTTP-Anforderungsobjekts gesendet werden. Die Anforderung kann entweder einen HTTP-Header oder einen HTTP-Body oder beides enthalten.

Erstellen wir daher eine HTTP-Entität und senden die Header und Parameter in body.

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. Class-java.lang.Object ...-


1
Sie können diesen Link auch für weitere Informationen verweisen techie-mixture.blogspot.com/2016/07/…
Tharsan Sivakumar

1
Du hast meinen Tag gerettet, ich habe erwartet, dass die Verwendung von Resttemplate ziemlich offensichtlich ist, aber es gibt einige Tricks!
Sergii Getman

1
ResponseEntity<String> response = new RestTemplate().postForEntity(url, request, String.class);Ich org.springframework.http.converter.HttpMessageNotWritableExc‌​eption: Could not write content: No serializer found for class java.util.Collections$3
bekomme

Wie man Körperparameter übergibt, wenn andere Strings sind, aber einer von ihnen vom Typ String [] ist, wie in den folgenden Anforderungsdaten argsist ein Array von Stringcurl -X POST --data '{"file": "/xyz.jar", "className": "my.class.name", "args": ["100"]}' -H "Content-Type: application/json" localhost:1234/batches
khawarizmi

2
Das funktioniert also nur für Strings ... Was ist, wenn ich ein Java-Objekt in Payload senden möchte?
Devssh

23

So veröffentlichen Sie gemischte Daten: Datei, Zeichenfolge [], Zeichenfolge in einer Anforderung.

Sie können nur das verwenden, was Sie benötigen.

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;
}

Die POST-Anforderung enthält Datei in ihrem Hauptteil und in der nächsten Struktur:

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

Ich habe diese Methode ausprobiert, aber bei mir nicht funktioniert. Ich habe ein Problem mit einer POST-Anfrage mit den Daten im mehrteiligen Format. Hier ist meine Frage, ob Sie mich mit einer Lösung führen könnten stackoverflow.com/questions/54429549/…
Deep Lathia

8

Hier ist das vollständige Programm zum Ausführen eines POST-Restaufrufs mit Spring's RestTemplate.

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
Das postet application / json anstelle von Formulardaten
Maciej Stępyra

ResponseEntity<?> response = new RestTemplate().postForEntity(url, request, String.class);. Ich org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: No serializer found for class java.util.Collections$3
bekomme

Könnten Sie bitte Ihr gesamtes Programm teilen oder mich wissen lassen, dass ich ein Beispielprogramm teilen werde @ShivkumarMallesappa
Piyush Mittal

Wenn Sie den application/jsonInhaltstyp durch den ersetzen, application/x-www-form-urlencodederhalten Sie org.springframework.web.client.RestClientException: Kein HttpMessageConverter für java.util.HashMap und Inhaltstyp "application / x-www-form-urlencoded" - siehe stackoverflow.com/q / 31342841/355438
Lu55

-3

Ihre URL-Zeichenfolge benötigt variable Markierungen für die Karte, die Sie an die Arbeit übergeben, z.

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

Oder Sie können die Abfrageparameter zunächst explizit in den String codieren und müssen die Map überhaupt nicht übergeben, z. B.:

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

Siehe auch https://stackoverflow.com/a/47045624/1357094

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.