Skip to main content

How to send a simple POST request to a web server?

7 replies [Last post]
arhus
Offline
Joined: 2007-11-29

Hi,

I would appreciate any example that shows how to make a connection to a web server and send a POST request. I can easily send a GET request, but I am failing sending a POST request. Please advise.

Here is what I tried:

1. Create HttpURLConnection, open OutputStream and write the data. Failed, because the server never got the data.
2. Create a socket connection and write the headers and data to the stream. Failed, because the server refused connection.

Maybe I am doing something wrong...

Thanks,

Petr

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
tarbo
Offline
Joined: 2006-12-18

For (1), have you tried flushing the data? Have you included the Content-Length header so that the server knows when the input ends?
For (2), can you give an example header as sent by your code? Perhaps there is a HTTP syntax error somewhere? Was it sent to the correct port (default is 80) ? Perhaps there is a HTTP syntax error somewhere?

Sending data over networks tends to be a little tricky at first. ;)

arhus
Offline
Joined: 2007-11-29

Here is the code that uses HttpURLConnection. I am running Tomcat that listens on 8084 and reads the request parameters. The example below does not work, I cannot see the request parameters to be read successfuly by the JSP file (but GET method works). Can you write a simple server that listens on a socket and shows all the data sent to the socket?

String servlet = "http://localhost:8084/index.jsp";
String query = "act=1&id=350";
java.net.URL url = new java.net.URL(servlet);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
PrintWriter writer = new PrintWriter(conn.getOutputStream(), true);
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while (reader.ready()) {
System.out.print(reader.read());
}

writer.println("POST " + url.getPath() + " HTTP/1.1" +
"\nAccept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-ms-application, application/vnd.ms-xpsdocument, application/xaml+xml, application/x-ms-xbap, application/x-shockwave-flash, */*" +
"\nReferer: " + url +
"\nAccept-Language: cs" +
"\nContent-Type: application/x-www-form-urlencoded" +
"\nUA-CPU: x86" +
"\nAccept-Encoding: gzip, deflate" +
"\nUser-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)" +
"\nHost: " + url.getHost() + ":" + url.getPort() +
"\nContent-Length: " + query.length() +
"\nConnection: Keep-Alive" +
"\nCache-Control: no-cache" +
"\n\n" + query);
writer.close();
reader.close();
conn.disconnect();

tarbo
Offline
Joined: 2006-12-18

For writing, try to use the methods provided by the HttpURLConnection class. For instance:

[code]conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Content-Length", Integer.toString(query.length()));
conn.getOutputStream().write(query.getBytes(charEncoding));
conn.connect();[/code]

You could otherwise just as well use a normal Socket. ;)

For the server, you can run a class in a separate VM:

[code]public class PrintServer {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(8084);
Socket client = ss.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));
String line;
while ((line = br.readLine()) != null) System.out.println("CLN > " + line);
br.close();
ss.disconnect();
}
}[/code]
Not guaranteed to work out-of-the-box. :p

arhus
Offline
Joined: 2007-11-29

Hi tarbo,

thanks for your code. The server-side code works partially, it shows all the input until any response is required, i.e. it shows only the headers, but not the query itself.

However, the client-side code doesn't work. Please try to compile it and you will see that the PrintServer will throw a SocketException when it reaches the while loop.

I don't understand why the writing to the outputstream doesn't work. And what the java.net.URL.openConnection() method actualy does (does it only connect or does it send any header?).

tarbo
Offline
Joined: 2006-12-18

> However, the client-side code doesn't work. Please try to compile
> it and you will see that the PrintServer will throw a SocketException
> when it reaches the while loop.

Ah yes, my bad. The problem here is that the client closes the connection before the server gets a chance to send a response of some kind. That should be helped by putting [i]conn.getResponseCode()[/i] at the bottom of the client code, so that it waits for a server answer. (But our 'server' currently doesn't send a reply, so the client will block and you'll need to kill the process.)

> I don't understand why the writing to the outputstream doesn't
> work. And what the java.net.URL.openConnection() method
> actualy does

Plain writing usually doesn't work because the server needs some way of knowing how much input to expect (though it's possible chunked transfers can be used). If you know the length of your data in advance, it's good manners to put up a "Content-Length" header.

[i]openConnection()[/i] creates an object to serve a connection, and only that. This new object (subclass of URLConnection) is responsible for any network activity -- its [i]connect()[/i] method will send all headers so you can do input and output. Here's a little example:

[code]
*** Client calls openConnection() and sets headers
(Nothing happens on the network)
*** Client calls connect()
C: POST / HTTP/1.1
C: Host: foo
C:
*** Client calls getOutputStream().write();
C: I am sending some data you might like!
S: 200 OK
S:
*** Client calls getResponseCode();
(Nothing happens on the network, everything already sent.)
[/code]

The explicit call to [i]connect()[/i] isn't really needed -- headers are sent automatically when needed, so you can call [i]getOutputstream()[/i] immediately without going through [i]connect()[/i] first. So you could say connecting simply sends the headers. ;)

For reference, here is working client code.
[code]import java.net.*;
import java.io.*;

public class Client {
public static void main(String[] args) throws Exception {
String query = "Ping me with info, peeps.";
String charEncoding = "iso-8859-1";
String location = "http://localhost:8084/";

HttpURLConnection conn = (HttpURLConnection) new URL(location).openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Length", Integer.toString(query.length()));
conn.getOutputStream().write(query.getBytes(charEncoding));
conn.connect();
conn.getResponseCode();
}
}[/code]

arhus
Offline
Joined: 2007-11-29

Thanks tarbo for explaining me the connection process. I tried the example and it really works! Thanks a lot!

joyatiitr
Offline
Joined: 2009-06-21

Thanks from me too :)