I would like to send a POST request in Java. At the moment, I do it like this:
URL url = new URL("myurl");
URLConnection con = url.openConnection();
con.setDoOutput(true);
PrintStream ps = new PrintStream(con.getOutputStream());
ps.println("key=" + URLEncoder.encode("value"));
// we have to get the input stream in order to actually send the request
con.getInputStream();
ps.close();
I do not understand why I have to call con.getInputStream() in order to actually send the request. If I do not call it, the request is not sent.
Is there a problem using PrintStream? It should not matter if I take a PrintStream, PrintWriter or something else, right?
URL represents some source.
URLConnection represents a connection to the resource.
you need call connection.connect() to connect the connection
Try to add con.setDoInput (false); before writing to the output.
P.S.: and you should also call con.connect () as swanliu says.
Update
This is what I came up with
private static final void sendPostRequest (final String urlAddress, String key, String value) throws Exception
{
URL url = new URL (urlAddress);
URLConnection con = url.openConnection ();
con.setDoOutput (true);
con.setDoInput (false);
PrintStream ps = new PrintStream (con.getOutputStream ());
ps.println (key + "=" + URLEncoder.encode (value, "UTF-8"));
ps.flush ();
con.connect ();
ps.close ();
}
I checked with WireShark that a tcp connection is being established and that closed. But don't know how check that the server received the request.
If you have a quick way to check it you may try that code.
I think a post of another thread answered my question. Sorry, but I found it too late. You can find it here.
PS: Unfortunately, Stackoverflow added my last answer to the question as a comment, because my answer was too short. And it is not possible to mark a comment as the correct answer... Hope this one is long enough :-)
I think this is the easiest way.
con.setDoOutput(true);
PrintStream ps = new PrintStream(con.getOutputStream());
ps.print("&client_id="+ 2);
ps.print("&amount="+10);
ps.flush();
ps.close();
Related
Sorry for the very basic question, I am new to Java.
To get data from an URL I use code like this
URL url = new URL(BaseURL+"login?name=foo");
URLConnection yc = url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
while ((inputLine = in.readLine()) != null)
...
That works perfectly fine. When I now want to continue and send the next command to the server (like ".../getStatus"), do I need to create these objects over and over again, or is there a smarter way?
Thanks!
You have to call openConnection again in order to get a new URLConnection. The HttpURLConnection does internal caching, though, so if the HTTP-server supports Connection: keep-alive the underlying connection to the server will be reused so it's not that bad as it originally might look. It's just hidden from you.
I looked into the Apache HttpComponents (HttpClient) and it still requires a lot of code. As I don't need cookie-handling (it's only a simple RESTful server giving json-blocks as responses) I'm going for a very simple solution:
public static String readStringFromURL(String requestURL) throws IOException
{
URL u = new URL(requestURL);
try (InputStream in = u.openStream()) {
return new String(in.readAllBytes(), StandardCharsets.UTF_8);
}
}
For me that looks like a perfect solution, but as mentioned, I am new to Java and open (and thankful) for hints...
I'm trying to get an image hosting on our server available to be displayed on a client. As per the specs of the project:
"When a Client receives such a URL, it must download the
contents (i.e., bytes) of the file referenced by the URL.
Before the Client can display the image to the user, it must first retrieve (i.e., download) the bytes of the
image file from the Server. Similarly, if the Client receives the URL of a known data file or a field help file
from the Server, it must download the content of those files before it can use them."
I'm pretty sure we have the server side stuff down, because if I put the url into a browser it retrieves and displays just fine. So it must be something with the ClientCommunicator class; can you take a look at my code and tell me what the problem is? I've spent hours on this.
Here is the code:
Where I actually call the function to get and display the file: (This part is working properly insofar as it is passing the right information to the server)
JFrame f = new JFrame();
JButton b = (JButton)e.getSource();
ImageIcon image = new ImageIcon(ClientCommunicator.DownloadFile(HOST, PORT, b.getLabel()));
JLabel l = new JLabel(image);
f.add(l);
f.pack();
f.setVisible(true);
From the ClientCommunicator class:
public static byte[] DownloadFile(String hostname, String port, String url){
String image = HttpClientHelper.doGetRequest("http://"+hostname+":"+port+"/"+url, null);
return image.getBytes();
}
The pertinent httpHelper:
public static String doGetRequest(String urlString,Map<String,String> headers){
URL url;
HttpURLConnection connection = null;
try {
//Create connection
url = new URL(urlString);
connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Content-Language", "en-US");
connection.setUseCaches (false);
connection.setDoInput(true);
connection.setDoOutput(true);
if(connection.getResponseCode() == 500){
return "failed";
}
//Get Response
InputStream is = connection.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer response = new StringBuffer();
while((line = rd.readLine()) != null) {
response.append(line);
}
rd.close();
return response.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if(connection != null) {
connection.disconnect();
}
}
}
After that, it jumps into the server stuff, which as I stated I believe is working correctly because clients such as Chrome can retrieve the file and display it properly. The problem has to be somewhere in here.
I believe that it has to do with the way the bytes are converted into a string and then back, but I do not know how to solve this problem. I've looked at similar problems on StackOverflow and have been unable to apply them to my situation. Any pointers in the right direction would be greatly appreciated.
If your server is sending binary data, you do not want to use an InputStreamReader, or in fact a Reader of any sort. As the Java API indicates, Readers are for reading streams of characters (not bytes) http://docs.oracle.com/javase/7/docs/api/java/io/Reader.html, which means you will run into all sorts of encoding issues.
See this other stack overflow answer for how to read bytes from a stream:
Convert InputStream to byte array in Java
Do your homework.
Isolate the issue. Modify the server side to send only 256 all possible bytes. Do a binary search and reduce it to small set of bytes.
Use http proxy tools to monitor the bytes as they are transmitted. Fiddler in windows world. Find other ones for the *nix environments.
Then see where the problem is happening and google/bing the suspicions or share the result.
If the temp string is very large I get java.io.IOException: Error writing to server at getInputStream
String tmp = js.deepSerialize(taskEx);
URL url = new URL("http://"
+ "localhost"
+ ":"
+ "8080"
+ "/Myproject/TestServletUpdated?command=startTask&taskeId=" +taskId + "'&jsonInput={\"result\":"
+ URLEncoder.encode(tmp) + "}");
URLConnection conn = url.openConnection();
InputStream is = conn.getInputStream();
Why is that?
This call goes to the servlet mentioned in the URL.
Use HTTP POST method instead of putting all the data in the URL for GET method. There is an upper limit for the length of the URL, so you need to use POST method if you want to send arbitrary length data.
You may want to modify the URL to http://localhost:8080/Myproject/TestServletUpdated, and put the rest
command = "startTask&taskeId=" + taskId + "'&jsonInput={\"result\":" + URLEncoder.encode(tmp) + "}"
in the body of the POST request.
I think you might have a "too long url", the maximum number of characters are 2000 (see this SO post for more info). GET requests are not made to handle such long data input.
You can, if you can change the servlet code also, change it into a POST instead of a GET request (as you have today). The client code would look pretty simular:
public static void main(String[] args) throws IOException {
URL url = new URL("http", "localhost:8080", "/Myproject/TestServletUpdated");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write("command=startTask" +
"&taskeId=" +taskId +
"&jsonInput={\"result\":" + URLEncoder.encode(tmp) + "}");
wr.flush();
.... handle the answer ...
}
I didn't see it first but it seems like you have a single quote character in your request string.
...sk&taskeId=" + taskId + "'&jso.....
^
try removing it, it might help you!
getInputStream() is used to read data. Use getOutputStream()
It could be because the request is being sent as a GET which has a limitation of a very few characters. When the limit exceeds you get an IOException. Convert that to POST and it should work.
For POST
URLConnection conn = url.openConnection().
OutputStream writer = conn.getOutputSteam();
writer.write("yourString".toBytes());
Remove the temp string from the url that you are passing. Move the "command" string to the "yourString".toBytes() section in the code above
I'm trying to open http connection to some given URL in the following form:
http://example.com/xml.aspx?RssType=1&TypeName=中文
I wanted to open an Http connection to it, get its inputStream, and do some parsing on the inputstream (see the code snippet below). But all I get is a MalformedURLException.
Anyone has any idea what's wrong with this URL? is the parameters "?Rss...&..." that's causing the problem or the non-ASCII chars at the end that are problematic?
Code snippet:
String feed = getString(R.string.feed_url);
URL url = null;
HttpURLConnection httpConn = null;
try {
url = new URL(feed);
httpConn = (HttpURLConnection) url.openConnection();
if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) { // exception here!
You need to URL-encode the parameters, in particular that 中文 bit.
Use java.net.URLEncoder.encode("中文", "UTF-8") — to be on the safe side, for every parameter value of the query, not only of TypeName.
I'm a problem with a HttpsURLConnection that I can't seem to solve. Basically, I'm sending up some info to a server and if some of that data is wrong, the server sends me a 500 response code. However, it also sends a message in the response telling me which bit of data was wrong. The problem is that the message is always empty when I read it in. I think this is because a filenotfound exception always gets thrown before the stream can be read. Am I right? I tried reading the errorstream as well but this is always empty. Here's a snippet:
conn = (HttpsURLConnection) connectURL.openConnection();
conn.setDoOutput(true);
conn.setConnectTimeout(30000);
conn.setReadTimeout(30000);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Length",
Integer.toString(outString.getBytes().length));
DataOutputStream wr = new DataOutputStream(conn
.getOutputStream());
wr.write(outString.getBytes());
wr.flush();
wr.close();
if(conn.getResponseCode>400{
String response = getErrorResponse(conn);
public String getErrorResponse(HttpsURLConnection conn) {
Log.i(TAG, "in getResponse");
InputStream is = null;
try {
//is = conn.getInputStream();
is = conn.getErrorStream();
// scoop up the reply from the server
int ch;
StringBuffer sb = new StringBuffer();
while ((ch = is.read()) != -1) {
sb.append((char) ch);
}
//System.out.println(sb.toString());
return sb.toString();
// return conferenceId;
}
catch (Exception e){
e.printStackTrace();
}
}
So just to follow up on this, here is how I solved it:
public static String getResponse(HttpsURLConnection conn) {
Log.i(TAG, "in getResponse");
InputStream is = null;
try {
if(conn.getResponseCode()>=400){
is = conn.getErrorStream();
}
else{
is=conn.getInputStream();
}
...read stream...
}
It seems that calling them like this produced an error stream with a message. Thanks for the suggestions!
Try setting content-type request property to "application/x-www-form-urlencoded"
The same is mentioned on this link:
http://developers.sun.com/mobility/midp/ttips/HTTPPost/
The Content-Length and Content-Type headers are critical because they tell the web server how many bytes of data to expect, and what kind, identified by a MIME type.
In MIDP clients the two most popular MIME types are application/octet-stream, to send raw binary data, and application/x-www-form-urlencoded, to send name-value pairs
Are you in control of the server? In other words, did you write the process that runs on the server and listens to the port you're trying to access?
If you did, then you should also be able to debug it and see why your process returns 404.
If you didn't, then describe your architecture (HTTP server, the component it invokes to respond to your HTTP(S) request, etc) and we'll take it from there.
In the very simplest case, of an HTTP server being an Apache server yielding control to some PHP script, it means that Apache couldn't assign your request to anything. Most likely a Web server misconfiguration. Provide some more details and we'll help you out.