Как отправить данные формы с помощью Spring RestTemplate?

149

Я хочу преобразовать следующий (рабочий) фрагмент curl в вызов RestTemplate:

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

Как правильно передать параметр электронной почты? Следующий код приводит к ответу 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 );

Я попытался сформулировать правильный вызов в PostMan, и я могу заставить его работать правильно, указав параметр email в качестве параметра «form-data» в теле. Как правильно достичь этой функциональности в RestTemplate?

сим
источник
Попробуйте restTemplate.exchange ();
Мы Борг,
Какой тип содержания URL вы указали здесь?
Тарсан Сивакумар
Посмотрите на этот блог, который пытается сделать то же самое, я думаю, techie-mixture.blogspot.com/2016/07/…
Тарсан Сивакумар
@TharsanSivakumar URL вернет JSON.
Сим
Возможный дубликат RestTemplate uriVariables не расширен
виолончель

Ответы:

357

Метод POST должен быть отправлен вдоль объекта HTTP-запроса. И запрос может содержать либо заголовок HTTP или тело HTTP, либо оба.

Поэтому давайте создадим объект HTTP и отправим заголовки и параметры в теле.

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. Класс-java.lang.Object ...-

Тарсан Сивакумар
источник
1
Вы можете также обратиться по этой ссылке для получения дополнительной информации techie-mixture.blogspot.com/2016/07/…
Тарсан Сивакумар,
1
Вы спасли мой день, я ожидал, что использование resttemplate довольно очевидно, но есть некоторые хитрости!
Сергей Гетьман
1
ResponseEntity<String> response = new RestTemplate().postForEntity(url, request, String.class);Я получаюorg.springframework.http.converter.HttpMessageNotWritableExc‌​eption: Could not write content: No serializer found for class java.util.Collections$3
Шивкумар Маллесаппа
Как передать параметр body, когда другие являются строками, но одна из них имеет тип String [], как argscurl -X POST --data '{"file": "/xyz.jar", "className": "my.class.name", "args": ["100"]}' -H "Content-Type: application/json" localhost:1234/batches
показано
2
Так что это работает только для строк ... Что если я хочу отправить объект Java в полезной нагрузке?
Devssh
23

Как разместить смешанные данные: File, String [], String в одном запросе.

Вы можете использовать только то, что вам нужно.

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

Запрос POST будет иметь File в своем теле и следующую структуру:

POST https://my_url?array=your_value1&array=your_value2&name=bob 
Юлия Ашомок
источник
Я попробовал этот метод, но у меня не получилось. Я столкнулся с проблемой создания POST-запроса с данными в многочастном формате. Вот мой вопрос, если бы вы могли помочь мне с решением stackoverflow.com/questions/54429549/…
Deep Lathia
8

Вот полная программа для вызова POST rest с использованием Spring 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
Это публикует приложение / JSON вместо данных формы
Maciej Stępyra
ResponseEntity<?> response = new RestTemplate().postForEntity(url, request, String.class);, Я получаюorg.springframework.http.converter.HttpMessageNotWritableException: Could not write content: No serializer found for class java.util.Collections$3
Шивкумар Маллесаппа
не могли бы вы поделиться всей своей программой или дать мне знать, что я поделюсь примером программы @ShivkumarMallesappa
Миттал
Если заменить application/jsonтип содержания, который application/x-www-form-urlencodedвы получите org.springframework.web.client.RestClientException: Нет HttpMessageConverter для java.util.HashMap и типа содержимого «применение / х-WWW-форм-urlencoded» - см stackoverflow.com/q / 31342841/355438
Lu55,
-3

Ваша строка url нуждается в переменных маркерах для карты, которую вы передаете на работу, например:

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

Или вы могли бы явно кодировать параметры запроса в String для начала и не передавать карту вообще, например:

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

Смотрите также https://stackoverflow.com/a/47045624/1357094

cellepo
источник