I'm trying to upload image to a image hosting site (fastpic.ru) but I can't get right response as I expected. I used fiddler to check would I send right param and everything seems are fine but I can't get right response. Could you guide me how to upload and get response in proper way?
Right response I mean I should receive something like http://fastpic.ru/session/2012/0425/Y6sEtGjtT1.html but I only receive http://fastpic.ru/index.php
Thank you
This is my code
String urlToConnect = "http://fastpic.ru/uploadmulti";
String boundary = Long.toHexString(System.currentTimeMillis()); // Generate random boundary
URLConnection connection = new URL(urlToConnect).openConnection();
connection.setDoOutput(true); // This sets request method to POST.
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
OutputStream output = null;
PrintWriter writer = null;
try {
output = connection.getOutputStream();
writer = new PrintWriter(new OutputStreamWriter(output, "UTF-8"), true); // true = Autoflush, important!
writer.println("-----------------------------" + boundary);
writer.println("Content-Disposition: form-data; name=\"file[]\"; filename=\"" + fileToUpload.getName() + "\"");
writer.println("Content-Type: image/jpeg");
writer.println();
InputStream input = null;
try {
input = new FileInputStream(fileToUpload);
byte[] buffer = new byte[1024];
for (int length = 0; (length = input.read(buffer)) > 0;) {
output.write(buffer, 0, length);
}
output.flush();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException logOrIgnore) {
}
}
}
writer.println();
writer.println("-----------------------------" + boundary);
writer.println("Content-Disposition: form-data; name=\"submit\"");
writer.println();
writer.println("Загрузить");
writer.println("-----------------------------" + boundary);
writer.println("Content-Disposition: form-data; name=\"uploading\"");
writer.println();
writer.println("1");
writer.println("-----------------------------" + boundary + "--");
} finally {
if (writer != null) {
writer.close();
}
}
BufferedReader in = new BufferedReader(
new InputStreamReader(
connection.getInputStream()));
String decodedString;
while ((decodedString = in.readLine()) != null) {
System.out.println(decodedString);
}
in.close();
If it isn't returning the right output, there is probably something incorrect with the input.
I would recommend using the Apache HTTP components, such as MultipartEntity at http://hc.apache.org/httpcomponents-client-ga/httpmime/apidocs/org/apache/http/entity/mime/MultipartEntity.html for POSTing this kind of data. If you're trying to manually encode your data, it would be quite easy to make a simple mistake that'll stop the entire thing from working. There are a lot of examples using the Apache components, and its pretty simple to use.
Related
I'm pretty new to OAuth and am trying to refresh a token using a simple java client. Everything seems to go ok (or I think it does), the problem is I can't tell from the response if it's a good one. The http response code is 200, but when trying to parse the response for access_token, I get a null. Also difficult to troubleshoot is the "raw" response is garbled, or encoded in some way. I was thinking maybe it's byte but it doesn't seem to be. Here's the code:
private static String getClientCredentials() {
String postParams = "grant_type=refresh_token&refresh_token=1234567890";
Pattern pat = Pattern.compile(".*\"access_token\"\\s*:\\s*\"([^\"]+)\".*");
String clientId = "myClientID123";
String clientSecret = "myClientSecret123";
String tokenUrl = "https://www.host.com/oauth2/tenant/token";
String auth = clientId + ":" + clientSecret;
String authentication = Base64.getEncoder().encodeToString(auth.getBytes());
BufferedReader reader = null;
HttpsURLConnection connection = null;
String returnValue = "";
try {
URL url = new URL(tokenUrl);
connection = (HttpsURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Authorization", "Basic " + authentication);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Accept", "application/x-www-form-urlencoded");
connection.setRequestProperty("Accept-Encoding", "gzip, deflate, br");
connection.setRequestProperty("Connection", "keep-alive");
connection.setDoOutput(true);
OutputStream outStream = connection.getOutputStream();
outStream.write(postParams.getBytes());
outStream.flush();
outStream.close();
System.out.println("Resp code: " + connection.getResponseCode());
System.out.println("Resp message: " + connection.getResponseMessage());
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line = null;
StringWriter out = new StringWriter(connection.getContentLength() > 0 ? connection.getContentLength() : 2048);
while ((line = reader.readLine()) != null) {
out.append(line);
}
String response = out.toString();
Matcher matcher = pat.matcher(response);
if (matcher.matches() && matcher.groupCount() > 0) {
returnValue = matcher.group(1);
}
System.out.println("response: " + response);
System.out.println("returnValue: " + returnValue);
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
}
}
connection.disconnect();
}
return returnValue;
}
Here's the console output, sorry, I had to screenshot it because the characters didn't paste right:
Response Screenshot
Am I trying something that isn't allowed or is there a way to decode the response so I can run the pattern match to extract only the access_token? Or am I going about it all wrong? Any help is greatly appreciated in advance!
I am trying to upload two images along with some parameters to a server through my android application. After having searched online and following the instructions from here and here, as well as other sources, I have the following code:
String boundary = "***" + System.currentTimeMillis() + "***";
String twoHyphens = "--";
String crlf = "\r\n";
String output = "";
try {
HttpURLConnection httpUrlConnection = null;
URL url = new URL(myUrl);
httpUrlConnection = (HttpURLConnection) url.openConnection();
httpUrlConnection.setUseCaches(false);
httpUrlConnection.setDoInput(true);
httpUrlConnection.setDoOutput(true);
httpUrlConnection.setRequestMethod("POST");
httpUrlConnection.setRequestProperty("Connection", "Keep-Alive");
httpUrlConnection.setRequestProperty("Cache-Control", "no-cache");
httpUrlConnection.setRequestProperty("ENCTYPE", "multipart/form-data");
httpUrlConnection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
DataOutputStream request = new DataOutputStream(httpUrlConnection.getOutputStream());
request.writeBytes(twoHyphens + boundary + crlf);
// Convert and add first image
ByteArrayOutputStream bao1 = new ByteArrayOutputStream();
params[0].compress(Bitmap.CompressFormat.JPEG, 100, bao1);
byte[] ba1 = bao1.toByteArray();
request.writeBytes("Content-Disposition: form-data; name=\"image1\";filename=\"image1\"" + crlf);
request.writeBytes(crlf);
request.write(ba1);
request.writeBytes(crlf);
request.writeBytes(twoHyphens + boundary + crlf);
// Convert and add second image
ByteArrayOutputStream bao2 = new ByteArrayOutputStream();
params[1].compress(Bitmap.CompressFormat.JPEG, 100, bao2);
byte[] ba2 = bao2.toByteArray();
request.writeBytes("Content-Disposition: form-data; name=\"image2\";filename=\"image2\"" + crlf);
request.writeBytes(crlf);
request.write(ba2);
request.writeBytes(crlf);
request.writeBytes(twoHyphens + boundary + crlf);
request.writeBytes("Content-Disposition: form-data; name=\"username\"" + crlf);
request.writeBytes(crlf);
request.writeBytes(username);
request.writeBytes(crlf);
request.writeBytes(twoHyphens + boundary + twoHyphens);
request.writeBytes("Content-Disposition: form-data; name=\"datestr\"" + crlf);
request.writeBytes(crlf);
request.writeBytes(timeStampString);
request.writeBytes(crlf);
request.writeBytes(twoHyphens + boundary + twoHyphens);
request.flush();
request.close();
int responseCode = httpUrlConnection.getResponseCode();
if (responseCode == HttpsURLConnection.HTTP_OK) {
InputStream responseStream = new BufferedInputStream(httpUrlConnection.getInputStream());
BufferedReader responseStreamReader = new BufferedReader(new InputStreamReader(responseStream, Charset.forName("UTF-8")));
String line;
while ((line = responseStreamReader.readLine()) != null) {
output = line;
Log.d(TAG, line);
}
responseStreamReader.close();
}
httpUrlConnection.disconnect();
if (output == "") {
httpResultsReturned = false;
} else {
httpResultsReturned = true;
}
} catch (ProtocolException e) {
e.printStackTrace();
return "failed";
} catch (MalformedURLException e) {
e.printStackTrace();
return "failed";
} catch (IOException e) {
e.printStackTrace();
return "failed";
}
On the server side I try to access the data as follows:
<?php
if($_SERVER['REQUEST_METHOD'] === 'POST'){
$image1 = $_FILES['image1']['name'];
$image2 = $_FILES['image2']['name'];
$datestr= $_POST['datestr'];
$username= $_POST['username'];
}
?>
Eventually, both images are successfully transmitted, however I cannot send/receive the extra parameters. I receive the responses correctly, but throughout all the php code (there are parts that I omitted in this question), it seems like none of the parameters are sent/received.
In this question, AndroSco shared the solution that worked for him, but in his php file it looks like he only accesses the image and not the parameter...
Since I don't have a lot of experience on this field, I believe that there is probably something very obvious that I do incorrectly/don't do at all!
Any suggestions will be appreciated!
Thanks!
After much frustration, I found the bug in my code. After having imported the two images in the transmitted message and when I wanted to import the other parameters, I wrote the boundary incorrectly. Instead of adding this:
request.writeBytes(twoHyphens + boundary + crlf);
having a new line at the end, I wrote this:
request.writeBytes(twoHyphens + boundary + twoHyphens);
adding two hyphens at the end of the line.
After replacing the twoHyphens with crlf, everything worked nicely!
The code below shows a method, downloadUrl(), that takes a String, "myurl," its parameter. There are only two possible urls that I ever send to it, and the behavior of the method is different for each.
when myurl = URL1, it uses a GET request and everything works fine.
when myurl = URL2, however, it uses a POST request, and the response from the php page indicates that the post parameters sent with the request were empty. You can see the line where I set the POST params, so I don't understand why it's sending no params?!
Thanks for any help!
-Adam.
private String downloadUrl(String myurl) throws IOException {
InputStream is = null;
String response = "";
try {
URL urlObject = new URL(myurl);
HttpURLConnection conn = (HttpURLConnection) urlObject.openConnection();
// find out if there's a way to incorporate these timeouts into the progress bar
// and what they mean for shitty network situations
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setDoInput(true);
// INSERTED QUICK CHECK TO SEE WHICH URL WE ARE LOADING FROM
// it's important because one is GET, and one is POST
if (myurl.equals(url2)){
Log.i(TAG, "dlurl() in async recognizes we are doing pre-call");
conn.setRequestMethod("POST");
conn.setDoOutput(true);
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
String postParams = "?phone=" + phone;
writer.write(postParams);
Log.i(TAG, "we're adding " + postParams + "to " + urlObject);
writer.flush();
writer.close();
os.close();
}
else {
conn.setRequestMethod("GET");
conn.connect();
}
// Starts the query
int responseCode = conn.getResponseCode();
Log.i(TAG, "from " + myurl + ", The response code from SERVER is: " + responseCode);
is = conn.getInputStream();
// Convert the InputStream into a string
// i guess we look up how to do this
if (responseCode == HttpsURLConnection.HTTP_OK) {
String line;
BufferedReader br = new BufferedReader(new InputStreamReader(is));
while ((line = br.readLine()) != null) {
response += line;
}
} else {
response = "from downloadUrl, php page response was not OK: " + responseCode;
}
// it's good to close these things?
is.close();
conn.disconnect();
Log.i(TAG, "response is " + response);
return response;
// Makes sure that the InputStream is closed after the app is
// finished using it.
} finally {
if (is != null) {
is.close();
}
}
}
try with following code block to send parameters of the POST request.
Map<String,String> params = new LinkedHashMap<>();
params.put("phone", "phone");
StringBuilder postPraamString = new StringBuilder();
for (Map.Entry<String,Object> param : params.entrySet()) {
if (postPraamString.length() != 0) postPraamString.append('&');
postPraamString.append(URLEncoder.encode(param.getKey(), "UTF-8"));
postPraamString.append('=');
postPraamString.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8"));
}
byte[] postDataBytes = postData.toString().getBytes("UTF-8");
writer.write(postDataBytes);
So I figured out the root of the problem...
In the line:
String postParams = "?phone=" + phone;
The problem was that leading question mark. The question mark should only be used in GET requests.
I'm trying to post a file to a ASP.NET WEB API (C#) Server with a local Java application.
Basically I'm trying to reproduce the following HTML code in Java SE:
<form name="form1" method="post" enctype="multipart/form-data" action="http://localhost:50447/api/files/">
<div>
<label for="image1">Image File</label>
<input name="image1" type="file" />
</div>
<div>
<input type="submit" value="Submit" />
</div>
What's the simplest way to do this? I'd like to avoid using Apache..
Something like:
String urlToConnect = "http://localhost:50447/api/files/";
String paramToSend = "";
File fileToUpload = new File("C:/Users/aa/Desktop/sample_signed.pdf");
String boundary = Long.toHexString(System.currentTimeMillis()); // Just generate some unique random value.
URLConnection connection = null;
try {
connection = new URL(urlToConnect).openConnection();
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
connection.setDoOutput(true); // This sets request method to POST.
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
PrintWriter writer = null;
try {
writer = new PrintWriter(new OutputStreamWriter(connection.getOutputStream(), "UTF-8"));
writer.println("--" + boundary);
writer.println("Content-Disposition: form-data; name=\"paramToSend\"");
writer.println("Content-Type: text/plain; charset=UTF-8");
writer.println();
writer.println(paramToSend);
writer.println("--" + boundary);
writer.println("Content-Disposition: form-data; name=\"fileToUpload\"; filename=\"sample_signed.pdf\"");
writer.println("Content-Type: text/plain; charset=UTF-8");
writer.println();
BufferedReader reader = null;
try {
try {
reader = new BufferedReader(new InputStreamReader(new FileInputStream(fileToUpload), "UTF-8"));
} catch (UnsupportedEncodingException | FileNotFoundException e1) {
e1.printStackTrace();
}
try {
for (String line; (line = reader.readLine()) != null;) {
writer.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
} finally {
if (reader != null) try { reader.close(); } catch (IOException logOrIgnore) {}
}
writer.println("--" + boundary + "--");
} catch (UnsupportedEncodingException e2) {
e2.printStackTrace();
} catch (IOException e2) {
e2.printStackTrace();
} finally {
if (writer != null) writer.close();
}
// Connection is lazily executed whenever you request any status.
int responseCode = 0;
try {
responseCode = ((HttpURLConnection) connection).getResponseCode();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(responseCode);
Using only URLConnections.. This code isn't working properly.. It sends the file, but some content is lost and I don't know why.. My HTML sample works perfectly..
Can you help me?
Thank you for your attention,
Best Regards.
You are using a reader and writer combination, while you are transferring binary data. You should use streams when working with binary data.
So instead of a BufferedReader, use a normal InputStream buffered to read the file and do not wrap the output stream you get from the URLConnection.
Read bytes instead of strings in the read loop. So replace the part starting with BufferedReader until the finally just before the boundary write with:
OutputStream output = connection.getOutputStream();
InputStream fileIn = new FileInputStream(fileToUpload);
try {
byte[] buffer = new byte[4096];
int length;
while ((length = fileIn.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
output.flush();
} finally {
if (fileIn != null) try { fileIn.close(); } catch (IOException logOrIgnore) {}
}
Solution: Another approach, using DataOutputStream.
FileInputStream fileInputStream = new FileInputStream(absolutePath);
URL url = new URL("http://localhost:50447/api/files/");
// Open a HTTP connection to the URL
conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true); // Allow Inputs
conn.setDoOutput(true); // Allow Outputs
conn.setUseCaches(false); // Don't use a Cached Copy
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("ENCTYPE", "multipart/form-data");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
conn.setRequestProperty("uploaded_file", filename);
dos = new DataOutputStream(conn.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\"" + fileName + "\"" + lineEnd);
dos.writeBytes(lineEnd);
// create a buffer of maximum size
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// read file and write it into form...
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
dos.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
// send multipart form data necesssary after file data...
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
// Responses from the server (code and message)
serverResponseCode = conn.getResponseCode();
String serverResponseMessage = conn.getResponseMessage();
System.out.println(serverResponseMessage);
fileInputStream.close();
dos.flush();
dos.close();
Following is my function to upload file GCS :
public void fileUpload(InputStream streamData, String fileName,
String content_type) throws Exception {
byte[] utf8Bytes = fileName.getBytes("UTF8");
fileName = new String(utf8Bytes, "UTF8");
URL url = new URL("http://bucketname.storage.googleapis.com"+"/"+"foldername/"+fileName);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("PUT");
conn.setRequestProperty("Accept", "application/x-www-form-urlencoded");
conn.setRequestProperty("Authorization", "OAuth " + GcsToken.getAccessToken());
conn.setRequestProperty("x-goog-meta-FileName", fileName);
conn.setRequestProperty("x-goog-meta-ContentType", content_type);
OutputStream os = conn.getOutputStream();
BufferedInputStream bfis = new BufferedInputStream(streamData);
byte[] buffer = new byte[1024];
int bufferLength = 0;
// now, read through the input buffer and write the contents to the file
while ((bufferLength = bfis.read(buffer)) > 0) {
os.write(buffer, 0, bufferLength);
}
System.out.println("response :: " + conn.getResponseMessage());// ?????
}
This code works fine to uplaod file, but
After removing last Sysout , it is not uploading file
System.out.println("response :: " + conn.getResponseMessage());
what is reason behind this ?
any help ?
thnaks
You need to close your OutputStream to indicate that you've finished writing the request body:
os.close();
You should also check the response code of the request:
if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
// Error handling code here.
}
The reason it was working before is because the getResponseMessage function blocks until the request is finished being sent and the reply is received. Without ever checking the response value, your function just exits and the HTTP request might not be finished sending.
Thanks for this clarification.
I already tried with os.close() also tried with os.flush(). but same problem. :(
at last i have updated my code:
while ((bufferLength = bfis.read(buffer)) > 0) {
os.write(buffer, 0, bufferLength);
}
os.close();
if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
//logger
}
Now I am able to upload file.
Thanks again.