HttpURLConnection POST, conn.getOutputStream() throwing Exception - java

I want to make a POST by using HttpURLConnection.
I am trying this in 2 ways, but I always get an excetion when doing: conn.getOutputStream();
The exception I get in both cases is:
java.net.SocketException: Operation timed out: connect:could be due to
invalid address
function1:
public void makePost(String title, String comment, File file) {
try {
URL servlet = new URL("http://" + "www.server.com/daten/web/test/testupload.nsf/upload?CreateDocument");
HttpURLConnection conn=(HttpURLConnection)servlet.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
String boundary = "---------------------------7d226f700d0";
conn.setRequestProperty("Content-type","multipart/form-data; boundary=" + boundary);
//conn.setRequestProperty("Referer", "http://127.0.0.1/index.jsp");
conn.setRequestProperty("Cache-Control", "no-cache");
OutputStream os = conn.getOutputStream(); //exception throws here!
DataOutputStream out = new DataOutputStream(os);
out.writeBytes("--" + boundary + "\r\n");
writeParam(INPUT_TITLE, title, out, boundary);
writeParam(INPUT_COMMENT, comment, out, boundary);
writeFile(INPUT_FILE, file.getName(), out, boundary);
out.flush();
out.close();
InputStream stream = conn.getInputStream();
BufferedInputStream in = new BufferedInputStream(stream);
int i = 0;
while ((i = in.read()) != -1) {
System.out.write(i);
}
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
or function 2:
public void makePost2(String title, String comment, File file) {
File binaryFile = file;
String boundary = Long.toHexString(System.currentTimeMillis()); // Just generate some unique random value.
URLConnection connection = null;
try {
connection = new URL("http://" + "www.server.com/daten/web/test/testupload.nsf/upload?CreateDocument").openConnection();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
PrintWriter writer = null;
try {
OutputStream output = connection.getOutputStream(); //exception throws here
writer = new PrintWriter(new OutputStreamWriter(output, CHARSET), true); // true = autoFlush, important!
// Send normal param.
writer.println("--" + boundary);
writer.println("Content-Disposition: form-data; name=\""+ INPUT_TITLE +"\"");
writer.println("Content-Type: text/plain; charset=" + CHARSET);
writer.println();
writer.println(title);
// Send binary file.
writer.println("--" + boundary);
writer.println("Content-Disposition: form-data; name=\""+ INPUT_FILE +"\"; filename=\"" + binaryFile.getName() + "\"");
writer.println("Content-Type: " + URLConnection.guessContentTypeFromName(binaryFile.getName()));
writer.println("Content-Transfer-Encoding: binary");
writer.println();
InputStream input = null;
try {
input = new FileInputStream(binaryFile);
byte[] buffer = new byte[1024];
for (int length = 0; (length = input.read(buffer)) > 0;) {
output.write(buffer, 0, length);
}
output.flush(); // Important! Output cannot be closed. Close of writer will close output as well.
} catch (IOException e) {
e.printStackTrace();
} finally {
if (input != null) try { input.close(); } catch (IOException logOrIgnore) {}
}
writer.println(); // Important! Indicates end of binary boundary.
// End of multipart/form-data.
writer.println("--" + boundary + "--");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (writer != null) writer.close();
}
}

The URL simply cannot be reached. Either the URL is wrong, or the DNS server couldn't resolve the hostname. Try a simple connect with a well-known URL to exclude one and other, e.g.
InputStream response = new URL("http://stackoverflow.com").openStream();
// Consume response.
Update as per the comments, you're required to use a proxy server for HTTP connections. You need to configure that in the Java side as well. Add the following lines before any attempt to connect to an URL.
System.setProperty("http.proxyHost", "proxy.example.com");
System.setProperty("http.proxyPort", "8080");
It suffices to do this only once during runtime.
See also:
Java guides - Networking and proxies

Without establishing the connection (which in this case requires 1 more step to be performed ie connect), transfer is not possible. connect() should be called after the connection is configured (ie after being done with the set***() on the connection).
What is missing is:
conn.connect();

Related

OutputStream ops makes error in android studio java

Hello i have this code that its supposed to update values in mysql, but the OutputStream ops is making my app crash. I have it run in AsyncTask but still makes error.
try {
URL url = new URL(connstring);
HttpURLConnection http = (HttpURLConnection) url.openConnection();
http.setRequestMethod("POST");
http.setDoInput(true);
http.setDoOutput(true);
OutputStream ops = http.getOutputStream(); //error occurs here
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(http.getOutputStream(), "UTF-8"));
data = URLEncoder.encode("visible", "UTF-8") + "=" + URLEncoder.encode(visible, "UTF-8")
+ "&&" + URLEncoder.encode("visible", "UTF-8") + "=" + URLEncoder.encode(option, "UTF-8");
writer.write(data);
writer.flush();
writer.close();
ops.close();
} catch (MalformedURLException ex) {
result = ex.getMessage();
} catch (IOException e) {
result = e.getMessage();
}
This is the error i get:
java.lang.SecurityException: Permission denied (missing INTERNET permission?)

How can Upload a file to Sharepoint?

private void uploadDocToSharePoint(String token, Resource resource, String folderName) {
try {
String uploadUrl = Utils.SHARE_POINT_DOMAIN + "_api/web/getfolderbyserverrelativeurl('" + folderName + "')/files/add(url='" + resource.getFilename() + "', overwrite=true)";
URL url = new URL(uploadUrl);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
// Set Header
httpConn.setDoOutput(true);
httpConn.setDoOutput(true);
httpConn.setRequestMethod("POST");
httpConn.setRequestProperty("Authorization", "Bearer " + token);
httpConn.setRequestProperty("accept", "application/json; odata=verbose");
httpConn.setRequestProperty("Content-Type", "application/xml");
OutputStream os = httpConn.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os, StandardCharsets.UTF_8);
osw.write("Just Some Text");
osw.flush();
osw.close();
os.close(); //don't forget to close the OutputStream
httpConn.connect();
System.out.println(httpConn.getResponseCode());
System.out.println(httpConn.getResponseMessage());
String result;
BufferedInputStream bis = new BufferedInputStream(httpConn.getInputStream());
ByteArrayOutputStream buf = new ByteArrayOutputStream();
int result2 = bis.read();
while(result2 != -1) {
buf.write((byte) result2);
result2 = bis.read();
}
result = buf.toString();
System.out.println(result);
} catch (Exception e) {
System.out.println("Error while reading file: " + e.getMessage());
}
}
httpConn.getResponseCode() is 400 and httpConn.getResponseMessage() is Bad Request.
I have tested this request with the URL generated in this class on Postman.
it works correctly.
so I am sure about url and token is correct.
It creates an Empty file successfully.
But as I mentioned the response status is 400 and Bad Request.
I am not sure what is wrong with the following class
Sharepoint guide here
My class copied from here
screenshot here
Pls follow Sharepoint guide here

EDIT: How do I send this post Request with parameters AND form-data like this postman screenshot in JAVA?

I'm trying to send a POST request to grab comments but it doesn't work in Java while it does work with postman.
I get an 403 Forbidden error, but on postman it retrieves the data i need just fine..
Here's the Java code I'm trying to use to replicate the behavior.
String targetUrl = YOUTBE_COMMENTS_AJAX_URL;
String urlParameters = "action_load_comments=1&order_by_time=True&filter=jBjXVrS8nXs";
String updatedURL = targetUrl + "?" + urlParameters;
URL url = null;
InputStream stream = null;
HttpURLConnection urlConnection = null;
try {
url = new URL(updatedURL);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("content-type", "multipart/form-data");
urlConnection.setRequestProperty("user-agent", "USER_AGENT");
urlConnection.setDoOutput(true);
String data = URLEncoder.encode("video_id", "UTF-8")
+ "=" + URLEncoder.encode(youtubeId, "UTF-8");
data += "&" + URLEncoder.encode("session_token", "UTF-8") + "="
+ URLEncoder.encode(xsrfToken, "UTF-8");
data += "&" + URLEncoder.encode("page_token", "UTF-8") + "="
+ URLEncoder.encode(pageToken, "UTF-8");
urlConnection.connect();
OutputStreamWriter wr = new OutputStreamWriter(urlConnection.getOutputStream());
wr.write(data);
wr.flush();
stream = urlConnection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(stream, "UTF-8"), 8);
String result = reader.readLine();
return result;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
Here's an example of what postman is sending in their headers
It seems like your problem is here (see inline comments):
DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
wr.writeBytes(urlParameters);
// you wrote your URL parameters into Body
wr.flush();
wr.close();
//You closed your body and told server - you are done with request
conn.getOutputStream().write(postDataBytes);
// you wrote data into closed stream - server does not care about it anymore.
You have to append your urlParameters directly to the URL when you open it
Then you have to write your Form Data into body as you do:
conn.getOutputStream().write(postDataBytes);
and then close output stream

Java uploading .png to server using php POST data

This is the method I have in my java application. It is reading the bytes correctly, I have logged to see if it was. The problem is that the php is not realizing the data is there. I have tested and the .php reads that $_POST is set, but is empty.
public void screenshot(BufferedImage screenshot) {
try {
ImageIO.write(screenshot, "png",
new File(Environment.getStorageDirectory().toString()
.concat(File.separator + SCRIPT_NAME + ".png")));
HttpURLConnection httpUrlConnection;
OutputStream outputStream;
BufferedInputStream fileInputStream;
BufferedReader serverReader;
int totalBytes;
String response = "";
String serverResponse = "";
String localFileName = Environment.getStorageDirectory().toString()
.concat(File.separator + SCRIPT_NAME + ".png");
// Establish a connection
httpUrlConnection = (HttpURLConnection) new URL(
"http://www.scripted.it/scriptoptions/utils/saveScreenshot.php?user="
+ SupraCrafter.statHandler.getUser())
.openConnection();
httpUrlConnection.setDoOutput(true);
httpUrlConnection.setDoInput(true);
httpUrlConnection.setRequestMethod("POST");
httpUrlConnection.setRequestProperty("Content-type",
"application/x-www-form-urlencoded");
outputStream = httpUrlConnection.getOutputStream();
// Buffered input stream
fileInputStream = new BufferedInputStream(new FileInputStream(
localFileName));
// Get the size of the image
totalBytes = fileInputStream.available();
// Loop through the files data
for (int i = 0; i < totalBytes; i++) {
// Write the data to the output stream
outputStream.write(fileInputStream.read());
}
// Close the output stream
outputStream.close();
// New reader to get server response
serverReader = new BufferedReader(new InputStreamReader(
httpUrlConnection.getInputStream()));
// Read the servers response
serverResponse = "";
while ((response = serverReader.readLine()) != null) {
serverResponse = serverResponse + response;
}
System.out.println(serverResponse);
// Close the buffered reader
serverReader.close();
} catch (Exception e) {
e.printStackTrace();
}
try {
URL url = new URL(
"http://scripted.it/scriptoptions/utils/setScreenshotStatus.php?user="
+ SupraCrafter.statHandler.getUser() + "&pass="
+ SupraCrafter.statHandler.getPass() + "&script="
+ SCRIPT_NAME + "&status=1");
BufferedReader in = new BufferedReader(new InputStreamReader(
url.openStream()));
in.close();
} catch (MalformedURLException e) {
} catch (IOException e) {
}
}
Here is the .php file:
<?
// Config
$uploadBase = "../screenshots/";
$uploadFilename = $_GET['user'] . ".png";
$uploadPath = $uploadBase . $uploadFilename;
// Upload directory
if(!is_dir($uploadBase))
mkdir($uploadBase);
// Grab the data
$incomingData = file_get_contents('php://input');
// Valid data?
if(!$incomingData)
die("No input data");
// Write to disk
$fh = fopen($uploadPath, 'w') or die("Error opening file");
fwrite($fh, $incomingData) or die("Error writing to file");
fclose($fh) or die("Error closing file");
echo "Success";
?>
It always echos 'no input data.'
You are not encoding the content with application/x-www-form-urlencoded. You should not simply copy the bytes into the HTTP payload, but instead encode it correctly.
application/x-www-form-urlencoded is not the only possible way of encoding it, multipart/form-data is another common choice. Both are supported by almost all webservers, and as a consequence by PHP.
A tutorial on how to encode using Java is here : http://www.devx.com/Java/Article/17679
Why don't you use Apache's HttpClient or similar library that already do that tedious work for you?
Apache HttpClient : http://hc.apache.org/httpcomponents-client-ga/

Image writing over URLConnection

I am trying to write an image over an HttpURLConnection.
I know how to write text but I am having real problems trying
to write an image
I have succeeded in writing to the local HD using ImageIO:
But I am trying to write Image by ImageIO on url and failed
URL url = new URL(uploadURL);
connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setDoInput(true);
connection.setUseCaches(false);
connection.setRequestProperty("Content-Type", "multipart/form-data;
boundary=" + boundary);
output = new DataOutputStream(connection.getOutputStream());
output.writeBytes("--" + boundary + "\r\n");
output.writeBytes("Content-Disposition: form-data; name=\"" + FIELD_NAME + "\";
filename=\"" + fileName + "\"\r\n");
output.writeBytes("Content-Type: " + dataMimeType + "\r\n");
output.writeBytes("Content-Transfer-Encoding: binary\r\n\r\n");
ImageIO.write(image, imageType, output);
the uploadURL is the url to an asp page on the server which will upload the image with the file name given in "content-Disposition: part.
now when I send this then asp page find the request and find the name of file. but does not find the file to be uploaded.
The problem is that when writing by ImageIO on URL what will the name of the file on which the ImageIO is writing,
So please help me how ImageIO will write an image on URLConnection and how can I know the name of the file which I have to use in the asp page to upload the file
Thanks for taking the time to read this post
Dilip Agarwal
First I believe that you should call io.flush() and then io.close() after writing image.
Second content type seems strange for me. It seems that you are trying to submit form while it is actually image. I do not know what does your asp expect but typically when I write code that should transfer file over HTTP I send appropriate content type, e.g. image/jpeg.
Here is for example code snippet I extracted from one small utility that I wrote and I am using during my current work:
URL url = new URL("http://localhost:8080/handler");
HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.setDoInput(true);
con.setDoOutput(true);
con.setUseCaches(false);
con.setRequestProperty("Content-Type", "image/jpeg");
con.setRequestMethod("POST");
InputStream in = new FileInputStream("c:/temp/poc/img/mytest2.jpg");
OutputStream out = con.getOutputStream();
copy(in, con.getOutputStream());
out.flush();
out.close();
BufferedReader r = new BufferedReader(new InputStreamReader(con.getInputStream()));
// obviously it is not required to print the response. But you have
// to call con.getInputStream(). The connection is really established only
// when getInputStream() is called.
System.out.println("Output:");
for (String line = r.readLine(); line != null; line = r.readLine()) {
System.out.println(line);
}
I used here method copy() that I took from Jakarta IO utils. Here is the code for reference:
protected static long copy(InputStream input, OutputStream output)
throws IOException {
byte[] buffer = new byte[12288]; // 12K
long count = 0L;
int n = 0;
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
count += n;
}
return count;
}
Obviously the server side must be ready to read the image content directly from POST body.
I hope this helps.
The OP seems lost into oblivion but for the benefit of Mister Kite :
// main method
URL url = new URL(uploadURL);
connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true); // triggers "POST"
// connection.setDoInput(true); // only if needed
connection.setUseCaches(false); // dunno
final String boundary = Long.toHexString(System.currentTimeMillis());
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary="
+ boundary);
output = new DataOutputStream(connection.getOutputStream());
try {
// image must be a File instance
flushMultiPartData(image, output, boundary);
} catch (IOException e) {
System.out.println("IOException in flushMultiPartData : " + e);
return;
}
// ...
private void flushMultiPartData(File file, OutputStream serverOutputStream,
String boundary) throws FileNotFoundException, IOException {
// SEE https://stackoverflow.com/a/2793153/281545
PrintWriter writer = null;
try {
// true = autoFlush, important!
writer = new PrintWriter(new OutputStreamWriter(serverOutputStream,
charsetForMultipartHeaders), true);
appendBinary(file, boundary, writer, serverOutputStream);
// End of multipart/form-data.
writer.append("--" + boundary + "--").append(CRLF);
} finally {
if (writer != null) writer.close();
}
}
private void appendBinary(File file, String boundary, PrintWriter writer,
OutputStream output) throws FileNotFoundException, IOException {
// Send binary file.
writer.append("--" + boundary).append(CRLF);
writer.append(
"Content-Disposition: form-data; name=\"binaryFile\"; filename=\""
+ file.getName() + "\"").append(CRLF);
writer.append("Content-Type: "
+ URLConnection.guessContentTypeFromName(file.getName()))
.append(CRLF);
writer.append("Content-Transfer-Encoding: binary").append(CRLF);
writer.append(CRLF).flush();
InputStream input = null;
try {
input = new FileInputStream(file);
byte[] buffer = new byte[1024];
for (int length = 0; (length = input.read(buffer)) > 0;) {
output.write(buffer, 0, length);
}
output.flush(); // Important! Output cannot be closed. Close of
// writer will close output as well.
} finally {
if (input != null) try {
input.close();
} catch (IOException logOrIgnore) {}
}
writer.append(CRLF).flush(); // CRLF is important! It indicates end of
// binary boundary.
}
You may want to add Gzip compression - see file corrupted when I post it to the servlet using GZIPOutputStream for a working class with or without Gzip. The ImageIO has no place here - just write the bytes past the wire and use ImageIO to your heart's content on the server. Based on #BalusC answer

Categories