Spring Boot
RestTemplate
FormUrlEncoded
HTTP POST
Java

Use RestTemplate with object as data and application/x-www-form-urlencoded content type?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

When an endpoint expects application/x-www-form-urlencoded, you cannot send an arbitrary Java object as JSON and hope Spring will translate it automatically. With RestTemplate, the usual approach is to map the object fields into a MultiValueMap<String, String>, set the correct Content-Type, and submit that as the request body.

Why a Plain Object Is Not Enough

RestTemplate knows how to serialize Java objects to JSON when the request is application/json. Form encoding is different. The server expects a body such as:

text
name=Alice&age=30&active=true

That is a flat key-value format, not a nested object document. So the client must provide form fields explicitly.

The Basic RestTemplate Pattern

The standard approach is:

  1. create headers with MediaType.APPLICATION_FORM_URLENCODED
  2. put form fields into a MultiValueMap
  3. wrap both in an HttpEntity
  4. call postForEntity or exchange
java
1import org.springframework.http.HttpEntity;
2import org.springframework.http.HttpHeaders;
3import org.springframework.http.MediaType;
4import org.springframework.http.ResponseEntity;
5import org.springframework.util.LinkedMultiValueMap;
6import org.springframework.util.MultiValueMap;
7import org.springframework.web.client.RestTemplate;
8
9public class FormPostExample {
10    public static void main(String[] args) {
11        RestTemplate restTemplate = new RestTemplate();
12
13        HttpHeaders headers = new HttpHeaders();
14        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
15
16        MultiValueMap<String, String> form = new LinkedMultiValueMap<>();
17        form.add("username", "alice");
18        form.add("password", "secret");
19        form.add("grant_type", "password");
20
21        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(form, headers);
22
23        ResponseEntity<String> response = restTemplate.postForEntity(
24            "https://example.com/token",
25            request,
26            String.class
27        );
28
29        System.out.println(response.getBody());
30    }
31}

This is the simplest working solution and the one most form-encoded APIs expect.

Converting a POJO into Form Fields

If your application already has a request object, do not pass the object directly. Convert it to a MultiValueMap first.

java
1import org.springframework.util.LinkedMultiValueMap;
2import org.springframework.util.MultiValueMap;
3
4public class LoginRequest {
5    private final String username;
6    private final String password;
7
8    public LoginRequest(String username, String password) {
9        this.username = username;
10        this.password = password;
11    }
12
13    public MultiValueMap<String, String> toFormData() {
14        MultiValueMap<String, String> form = new LinkedMultiValueMap<>();
15        form.add("username", username);
16        form.add("password", password);
17        return form;
18    }
19}

Then use requestObject.toFormData() when constructing the HttpEntity. This keeps the object model in your codebase without confusing it with the wire format.

When Repeated Keys Matter

One reason MultiValueMap is the correct container is that form bodies can repeat keys. For example, some APIs allow multiple scope values or repeated selection fields. A normal Map<String, String> would lose that behavior.

So even when the fields look simple, MultiValueMap is the right abstraction for form-encoded requests.

Debugging Server Rejections

If the server claims it did not receive the expected form fields, check these first:

  • the request Content-Type
  • field names and spelling
  • whether the API expects strings or a different field layout
  • whether the endpoint actually expects multipart or JSON instead of form encoding

Many failures that look like authentication or validation bugs are really request-format mismatches.

A Helper Method Keeps Call Sites Clean

If several endpoints in your application use form encoding, wrap the conversion and request creation in a helper instead of rebuilding MultiValueMap objects everywhere. That keeps controller and service code readable and makes it easier to change field naming or optional-form behavior in one place later.

Common Pitfalls

  • Sending a POJO directly while setting application/x-www-form-urlencoded and expecting JSON-style serialization.
  • Using a plain Map when the API can accept repeated form keys.
  • Forgetting to set Content-Type to MediaType.APPLICATION_FORM_URLENCODED.
  • Assuming nested objects will serialize naturally into form fields without explicit flattening.
  • Debugging response handling before confirming the request body matches the endpoint contract exactly.

Summary

  • Form-encoded requests in RestTemplate should usually use MultiValueMap<String, String>.
  • Set the request Content-Type to application/x-www-form-urlencoded explicitly.
  • Convert POJOs into form fields instead of posting the object directly.
  • Wrap the headers and form map in an HttpEntity.
  • Most issues come from mismatched wire format, not from RestTemplate itself.

Course illustration
Course illustration

All Rights Reserved.