How to send post request with x-www-form-urlencoded body

Java

Java Problem Overview


Request in postman

How in java, can I send a request with x-www-form-urlencoded header. I don't understand how to send a body with a key-value, like in the above screenshot.

I have tried this code:

String urlParameters =
  cafedra_name+ data_to_send;
URL url;
    HttpURLConnection connection = null;  
    try {
      //Create connection
      url = new URL(targetURL);
      connection = (HttpURLConnection)url.openConnection();
      connection.setRequestMethod("POST");
      connection.setRequestProperty("Content-Type", 
           "application/x-www-form-urlencoded");
			
      connection.setRequestProperty("Content-Length", "" + 
               Integer.toString(urlParameters.getBytes().length));
      connection.setRequestProperty("Content-Language", "en-US");  
			
      connection.setUseCaches (false);
      connection.setDoInput(true);
      connection.setDoOutput(true);

      //Send request
      DataOutputStream wr = new DataOutputStream (
                  connection.getOutputStream ());
      wr.writeBytes (urlParameters);
      wr.flush ();
      wr.close ();

But in the response, I don't receive the correct data.

Java Solutions


Solution 1 - Java

As you set application/x-www-form-urlencoded as content type so data sent must be like this format.

String urlParameters  = "param1=data1&param2=data2&param3=data3";

Sending part now is quite straightforward.

byte[] postData = urlParameters.getBytes( StandardCharsets.UTF_8 );
int postDataLength = postData.length;
String request = "<Url here>";
URL url = new URL( request );
HttpURLConnection conn= (HttpURLConnection) url.openConnection();           
conn.setDoOutput(true);
conn.setInstanceFollowRedirects(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); 
conn.setRequestProperty("charset", "utf-8");
conn.setRequestProperty("Content-Length", Integer.toString(postDataLength ));
conn.setUseCaches(false);
try(DataOutputStream wr = new DataOutputStream(conn.getOutputStream())) {
   wr.write( postData );
}

Or you can create a generic method to build key value pattern which is required for application/x-www-form-urlencoded.

private String getDataString(HashMap<String, String> params) throws UnsupportedEncodingException{
    StringBuilder result = new StringBuilder();
    boolean first = true;
    for(Map.Entry<String, String> entry : params.entrySet()){
        if (first)
            first = false;
        else
            result.append("&");    
        result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
        result.append("=");
        result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
    }    
    return result.toString();
}

Solution 2 - Java

For HttpEntity, the below answer works

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

For reference: https://stackoverflow.com/questions/38372422/how-to-post-form-data-with-spring-resttemplate

Solution 3 - Java

string urlParameters = "param1=value1&param2=value2";
string _endPointName = "your url post api";

var httpWebRequest = (HttpWebRequest)WebRequest.Create(_endPointName);

httpWebRequest.ContentType = "application/x-www-form-urlencoded";
httpWebRequest.Method = "POST";
httpWebRequest.Headers["ContentType"] = "application/x-www-form-urlencoded";

System.Net.ServicePointManager.ServerCertificateValidationCallback +=
                                                  (se, cert, chain, sslerror) =>
                                                  {
                                                      return true;
                                                  };


using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
                {
                    streamWriter.Write(urlParameters);
                    streamWriter.Flush();
                    streamWriter.Close();
                }
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();

using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
                {
                    var result = streamReader.ReadToEnd();
                }

Solution 4 - Java

Building off of Navoneel's answer, I like to use StreamEx's EntryStream.

Here is Naveoneel's method re-written.

private String getDataString(HashMap<String, String> params)
{
   return EntryStream.
      of(data).
      mapKeys(key -> URLEncoder.encode(key, StandardCharsets.UTF_8)).        // Encode the keys
      mapValues(value -> URLEncoder.encode(value, StandardCharsets.UTF_8)).  // Encode the values
      join("=").                                                             // Create a key=value
      joining("&");                                                          // Assemble into key1=value1&key2=value2...
}

Solution 5 - Java

Use Java 11 HttpClient

> The HTTP Client was added in Java 11. It can be used to request HTTP resources over the network. It supports HTTP/1.1 and HTTP/2, both synchronous and asynchronous programming models, handles request and response bodies as reactive-streams, and follows the familiar builder pattern.

https://openjdk.java.net/groups/net/httpclient/intro.html

HttpClient client = HttpClient.newHttpClient();;
HttpRequest request = HttpRequest.newBuilder()
        .uri(new URI(targetUrl))
        .POST(urlParameters)
        .headers("Content-Type", "application/x-www-form-urlencoded")
        .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmariView Question on Stackoverflow
Solution 1 - JavaNavoneel TalukdarView Answer on Stackoverflow
Solution 2 - JavaNutanView Answer on Stackoverflow
Solution 3 - JavaMohsen MiriView Answer on Stackoverflow
Solution 4 - JavaNathanView Answer on Stackoverflow
Solution 5 - JavaSorterView Answer on Stackoverflow