¿Cómo enviar datos de formulario con Spring RestTemplate?

149

Quiero convertir el siguiente fragmento de rizo (en funcionamiento) en una llamada RestTemplate:

curl -i -X POST -d "[email protected]" https://app.example.com/hr/email

¿Cómo paso el parámetro de correo electrónico correctamente? El siguiente código da como resultado una respuesta 404 No encontrado:

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

Traté de formular la llamada correcta en PostMan, y puedo hacer que funcione correctamente especificando el parámetro de correo electrónico como un parámetro de "datos de formulario" en el cuerpo. ¿Cuál es la forma correcta de lograr esta funcionalidad en un RestTemplate?

sim
fuente
Pruebe restTemplate.exchange ();
Somos Borg
¿Cuál es el tipo de contenido aceptable de la URL que ha proporcionado aquí?
Tharsan Sivakumar
Mira este blog que está tratando de hacer lo mismo, supongo que techie-mixture.blogspot.com/2016/07/…
Tharsan Sivakumar
@TharsanSivakumar La url devolverá JSON.
sim
Posible duplicado de RestTemplate uri Variables no expandidas
cellepo

Respuestas:

357

El método POST debe enviarse junto con el objeto de solicitud HTTP. Y la solicitud puede contener un encabezado HTTP o un cuerpo HTTP o ambos.

Por lo tanto, creemos una entidad HTTP y enviemos los encabezados y el parámetro en el cuerpo.

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

Tharsan Sivakumar
fuente
1
También puede consultar este enlace para obtener más información techie-mixture.blogspot.com/2016/07/…
Tharsan Sivakumar
1
Me salvaste el día, esperaba que el uso de resttemplate sea ​​bastante obvio, ¡pero hay algunos trucos!
Sergii Getman
1
ResponseEntity<String> response = new RestTemplate().postForEntity(url, request, String.class);Me estoy poniendoorg.springframework.http.converter.HttpMessageNotWritableExc‌​eption: Could not write content: No serializer found for class java.util.Collections$3
Shivkumar Mallesappa
Cómo pasar el parámetro body cuando otros son Strings pero uno de ellos es de tipo String [], ya que en los datos de la solicitud a continuación argshay una matriz de Stringcurl -X POST --data '{"file": "/xyz.jar", "className": "my.class.name", "args": ["100"]}' -H "Content-Type: application/json" localhost:1234/batches
khawarizmi
2
Entonces, esto funciona solo para cadenas ... ¿Qué sucede si quiero enviar un objeto Java en la carga útil?
devssh
23

Cómo POSTAR datos mixtos: Archivo, Cadena [], Cadena en una solicitud.

Puede usar solo lo que necesita.

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 solicitud POST tendrá Archivo en su cuerpo y la siguiente estructura:

POST https://my_url?array=your_value1&array=your_value2&name=bob 
Yuliia Ashomok
fuente
Probé este método pero no funcionó para mí. Estoy enfrentando un problema al hacer una solicitud POST con los datos en formato multiparte. Aquí está mi pregunta si podría guiarme con una solución stackoverflow.com/questions/54429549/…
Deep Lathia
8

Aquí está el programa completo para hacer una llamada POST rest utilizando 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());
    }

}
Piyush Mittal
fuente
77
Que publica application / json en lugar de datos de formulario
Maciej Stępyra
ResponseEntity<?> response = new RestTemplate().postForEntity(url, request, String.class);. Estoy recibiendoorg.springframework.http.converter.HttpMessageNotWritableException: Could not write content: No serializer found for class java.util.Collections$3
Shivkumar Mallesappa
¿podría compartir todo su programa o hágamelo saber? Compartiré un ejemplo de programa de muestra @ShivkumarMallesappa
Piyush Mittal
Si reemplaza el application/jsontipo de contenido por el application/x-www-form-urlencodedobtendrá org.springframework.web.client.RestClientException: No HttpMessageConverter para java.util.HashMap y tipo de contenido "application / x-www-form-urlencoded" - consulte stackoverflow.com/q / 31342841/355438
Lu55
-3

Su url String necesita marcadores variables para el mapa que pasa al trabajo, como:

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

O podría codificar explícitamente los parámetros de consulta en la Cadena para comenzar y no tener que pasar el mapa, como:

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

Ver también https://stackoverflow.com/a/47045624/1357094

cellepo
fuente