HttpURLConnection
POST request
NameValuePair
Java coding
HTTP parameters

How to add parameters to HttpURLConnection using POST using NameValuePair

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

HttpURLConnection does not know how to send Apache NameValuePair objects directly. What it needs is a properly encoded byte body written to the connection output stream, usually in application/x-www-form-urlencoded format when you are sending ordinary form parameters.

What HttpURLConnection Actually Expects

A lot of confusion comes from mixing data structures with wire formats. NameValuePair is only a convenient Java representation of key-value inputs. The HTTP server never sees that object. It only sees bytes.

For a classic HTML form-style POST, the body must look like this:

text
username=alice&message=hello+world

That means you have to:

  1. URL-encode the names and values.
  2. Join them with = and &.
  3. Write the resulting bytes to the request body.

Build the Form Body

If you already have your parameters in a map, you can encode them like this:

java
1import java.net.URLEncoder;
2import java.nio.charset.StandardCharsets;
3import java.util.LinkedHashMap;
4import java.util.Map;
5import java.util.stream.Collectors;
6
7Map<String, String> params = new LinkedHashMap<>();
8params.put("username", "alice");
9params.put("message", "hello world");
10
11String formBody = params.entrySet()
12    .stream()
13    .map(e -> URLEncoder.encode(e.getKey(), StandardCharsets.UTF_8)
14        + "="
15        + URLEncoder.encode(e.getValue(), StandardCharsets.UTF_8))
16    .collect(Collectors.joining("&"));

Using LinkedHashMap is not required, but it preserves parameter order, which can be helpful for debugging and tests.

If You Already Use NameValuePair

If the inputs are already stored as Apache NameValuePair objects, the conversion step is almost the same.

java
1import org.apache.http.NameValuePair;
2import org.apache.http.message.BasicNameValuePair;
3
4import java.net.URLEncoder;
5import java.nio.charset.StandardCharsets;
6import java.util.List;
7import java.util.stream.Collectors;
8
9List<NameValuePair> pairs = List.of(
10    new BasicNameValuePair("username", "alice"),
11    new BasicNameValuePair("message", "hello world")
12);
13
14String formBody = pairs.stream()
15    .map(p -> URLEncoder.encode(p.getName(), StandardCharsets.UTF_8)
16        + "="
17        + URLEncoder.encode(p.getValue(), StandardCharsets.UTF_8))
18    .collect(Collectors.joining("&"));

Again, the important point is that HttpURLConnection receives the final encoded string, not the NameValuePair list.

Send the POST Request

Once the body string is ready, write it to the connection.

java
1import java.io.InputStream;
2import java.io.OutputStream;
3import java.net.HttpURLConnection;
4import java.net.URL;
5import java.nio.charset.StandardCharsets;
6
7URL url = new URL("https://example.com/api/form");
8HttpURLConnection conn = (HttpURLConnection) url.openConnection();
9byte[] bodyBytes = formBody.getBytes(StandardCharsets.UTF_8);
10
11conn.setRequestMethod("POST");
12conn.setDoOutput(true);
13conn.setConnectTimeout(5000);
14conn.setReadTimeout(5000);
15conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
16conn.setRequestProperty("Content-Length", String.valueOf(bodyBytes.length));
17
18try (OutputStream os = conn.getOutputStream()) {
19    os.write(bodyBytes);
20}
21
22int status = conn.getResponseCode();
23try (InputStream in = status >= 400 ? conn.getErrorStream() : conn.getInputStream()) {
24    if (in != null) {
25        String response = new String(in.readAllBytes(), StandardCharsets.UTF_8);
26        System.out.println(response);
27    }
28}

This is the real POST workflow: configure the request, write the encoded bytes, and read the response.

Do Not Confuse Form Posts With JSON Posts

A very common bug is sending name=value pairs while the server actually expects JSON. If the API contract says application/json, then the request body should be JSON, not form encoding.

That is why the first debugging question should always be: what format does the server expect?

  • If it expects form fields, use application/x-www-form-urlencoded.
  • If it expects JSON, build JSON and set Content-Type: application/json.

Same HTTP method, different body format.

Common Pitfalls

A common mistake is assuming NameValuePair objects will be serialized automatically by HttpURLConnection. They will not.

Another issue is forgetting setDoOutput(true). Without it, the connection is not prepared for a request body.

Developers also often skip URL encoding and then get broken requests when values contain spaces, ampersands, or non-ASCII characters.

Summary

  • 'HttpURLConnection expects an encoded byte body, not high-level parameter objects.'
  • For form-style POSTs, encode parameters as application/x-www-form-urlencoded.
  • 'NameValuePair can be a convenient intermediate container, but you still have to serialize it yourself.'
  • Set the method, headers, and output mode explicitly before writing the body.
  • Always match the request body format to what the server actually expects.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.