How to POST form data with Spring RestTemplate?
Asked Answered
H

4

240

I want to convert the following (working) curl snippet to a RestTemplate call:

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

How do I pass the email parameter correctly? The following code results in a 404 Not Found response:

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

I've tried to formulate the correct call in PostMan, and I can get it working correctly by specifying the email parameter as a "form-data" parameter in the body. What is the correct way to achieve this functionality in a RestTemplate?

Henkel answered 14/7, 2016 at 10:59 Comment(6)
Try restTemplate.exchange();Wherever
What's the acceptable content type of the url you have provided here ?Unroof
Look at this blog which is trying to do the same thing I guess techie-mixture.blogspot.com/2016/07/…Unroof
@TharsanSivakumar The url will return JSON.Henkel
Possible duplicate of RestTemplate uriVariables not expandedPredictory
You can visit bellow thread. It has full working code with description: https://mcmap.net/q/119331/-spring-resttemplate-exception-handlingArborization
U
503

The POST method should be sent along the HTTP request object. And the request may contain either of HTTP header or HTTP body or both.

Hence let's create an HTTP entity and send the headers and parameter in body.

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

Unroof answered 15/7, 2016 at 5:1 Comment(11)
You may refer this link as well for more info techie-mixture.blogspot.com/2016/07/…Unroof
ResponseEntity<String> response = new RestTemplate().postForEntity(url, request, String.class); I am getting org.springframework.http.converter.HttpMessageNotWritableExc‌​eption: Could not write content: No serializer found for class java.util.Collections$3Faraday
How to pass body parameter when others are Strings but one of them is of type String[], as in below request data args is an array of String curl -X POST --data '{"file": "/xyz.jar", "className": "my.class.name", "args": ["100"]}' -H "Content-Type: application/json" localhost:1234/batchesRutland
Any server side snippet available for this ?Weaponry
So this works only for strings... What if I want to send a java object in payload?Awful
No, you can pass objects as well, only thing you have to adjust your map accordingly. MultiValueMap<String, Object> map= new LinkedMultiValueMap<String, Object>();Unroof
@ShivkumarMallesappa :- I was also getting same error in spring boot application. we need to set below property in 'application.properties' spring.jackson.serialization.FAIL_ON_EMPTY_BEANS=falseTaxaceous
@ShivkumarMallesappa @SurajPatil When I try making the MultiValueMap<String, Object>, It is being received at the client as null (i.e all the values are null, except for one auto generated field). Also, name of the key and the parameter is same. any idea?Unplug
I'm getting java.lang.reflect.InvocationTargetExceptionCaelian
You have to add new FormHttpMessageConverter() to your RestTemplate's message converters to avoid non-suitable parser found error.Pulitzer
This is a good answer, but in my case did not fully work because the parameters were not inserted in the URI. I've managed to make it work following this + the suggestions in #8297715 to use UriComponentsBuilder or other methods to manipulate the URI in the RestTemplate.Instigation
H
37

How to POST mixed data: File, String[], String in one request.

You can use only what you need.

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

The POST request will have File in its Body and next structure:

POST https://my_url?array=your_value1&array=your_value2&name=bob 
Hols answered 28/5, 2017 at 12:55 Comment(1)
I tried this method but did not work for me. I am facing an issue making a POST request with the data in multipart format. Here's my question if you could guide me with a solution #54430049Nashoma
G
14

here is the full program to make a POST rest call using 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());
    }

}
Guillaume answered 16/1, 2017 at 4:40 Comment(4)
That posts application/json instead of form dataLacreshalacrimal
ResponseEntity<?> response = new RestTemplate().postForEntity(url, request, String.class);. I am getting org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: No serializer found for class java.util.Collections$3Faraday
could you please share your whole program or let me know i'll share some sample sample program @ShivkumarMallesappaGuillaume
If you replace application/json content type by the application/x-www-form-urlencoded you'll get org.springframework.web.client.RestClientException: No HttpMessageConverter for java.util.HashMap and content type "application/x-www-form-urlencoded" - see https://mcmap.net/q/119333/-using-a-map-to-set-parameters-for-a-rest-call-using-resttemplate/355438Elegy
S
1

Client.java

@PostMapping(value = "/employee", consumes = "application/json")
public Employee createProducts(@RequestBody Employee product) {
    HttpHeaders headers = new HttpHeaders();
    headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
    HttpEntity<Employee> entity = new HttpEntity<Employee>(product,headers);

    ResponseEntity<Employee> response = restTemplate.exchange(
            "http://hello-server/rest/employee", HttpMethod.POST, entity, Employee.class);

    return response.getBody();
}

Server.java

private static List<Employee> list = new ArrayList<>();

@PostMapping(path="rest/employee", consumes = "application/json")
public Employee createEmployee(@RequestBody Employee employee)

{
    list.add(employee);
    return employee;
}
static
{
    list.add(new Employee(1, "albert", "Associate", "mphasis"));
    list.add(new Employee(2, "sachin", "software engineer", "mphasis"));
    list.add(new Employee(3, "dhilip", "Lead engineer", "IBM"));
}

Employee.java

public class Employee {

private Integer id;
private String name;
private String Designation;
private String company;
 // generate getter setter and toString()
}

1. post request enter image description here

Streamy answered 19/7, 2021 at 18:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.