Downloading multimedia content in java from php pages - java

The url: http://www.teamliquid.net/replay/download.php?replay=1830 is a download link to a .rep file.
My question is: how to download this content in java knowing the name of the original rep file in order to save it with a defined prefix, like path/_.rep
//I was trying to run wget from java but I don't see how to get the original file's name.

Get the redirected URL,
http://www.teamliquid.net/replay/upload/coco%20vs%20snssoflsekd.rep
You can get the filename from this URL.
It's tricky to get the redirected URL. See my answer to this question on how to do it with Apache HttpClient 4,
HttpClient 4 - how to capture last redirect URL
EDIT: Here is a sample using HttpClient 4.0,
String url = "http://www.teamliquid.net/replay/download.php?replay=1830";
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(url);
HttpContext context = new BasicHttpContext();
HttpResponse response = httpClient.execute(httpget, context);
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK)
throw new IOException(response.getStatusLine().toString());
HttpUriRequest currentReq = (HttpUriRequest) context.getAttribute(
ExecutionContext.HTTP_REQUEST);
String currentUrl = URLDecoder.decode(currentReq.getURI().toString(), "UTF-8");
int i = currentUrl.lastIndexOf('/');
String fileName = null;
if (i < 0) {
fileName = currentUrl;
} else {
fileName = currentUrl.substring(i+1);
}
OutputStream os = new FileOutputStream("/tmp/" + fileName);
InputStream is = response.getEntity().getContent();
byte[] buf = new byte[4096];
int read;
while ((read = is.read(buf)) != -1) {
os.write(buf, 0, read);
}
os.close();
After running this code, I get this file,
/tmp/coco vs snssoflsekd.rep

Related

I can't figure out how to send a file via POST request to https://0x0.st in java

I can't figure out how to send a file via POST request to https://0x0.st in java
My code:
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addTextBody("key", key);
builder.addTextBody("client_id", client_id );
builder.addTextBody("direction_id", direction_id);
ContentType fileContentType = ContentType.create("image/jpeg");
String fileName = file.getName();
builder.addBinaryBody("client_files", file, fileContentType, fileName);
HttpEntity entity = builder.build();
Try this:
public static String uploadFile(String path, ContentType contentType) throws IOException {
File file = new File(path);
URI serverURL = URI.create("https://0x0.st/");
try(CloseableHttpClient client = HttpClientBuilder.create().build()) {
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addBinaryBody("file", file, contentType, file.getName());
HttpEntity requestEntity = builder.build();
HttpPost post = new HttpPost(serverURL);
post.setEntity(requestEntity);
try(CloseableHttpResponse response = client.execute(post)) {
HttpEntity responseEntity = response.getEntity();
int responseCode = response.getStatusLine().getStatusCode();
String responseString = EntityUtils.toString(responseEntity, "UTF-8");
if(responseCode == 200)
return responseString;
else throw new RuntimeException(responseCode + ": " + responseString);
}
}
}
The key for your upload must be file, url or shorten, otherwise you will get a 400 bad request response. If the request is successful, the provided code returns the URL for your uploaded file.
There are several Http clients available that you can try. The popular ones would be
Apache Http client
OK Http client.
I actually wrote my own Http client which is part of MgntUtils Open Source library written and maintained by me. The reason I wrote my own Http client is to provide a very simple option. It doesn't support all the features provided in other clients but is very simple in use, and it does support uploading and downloading binary information. Assuming from your code that key, client_id, and direction_id could be passed as request headers your code could be something like this
byte[] content = readFile() //Read file as bytes here
byte[] content = readFile() //Read file as bytes hereHttpClient client = new HttpClient();
client.setContentType("image/jpeg");
client.setRequestHeader("key", key);
client.setRequestHeader("client_id", client_id);
client.setRequestHeader("direction_id", direction_id);
String result = client.sendHttpRequest(" https://0x0.st", HttpMethod.POST, ByteBuffer.wrap(content));
System.out.println("Upload result: " + result); //If you expect any textual reply
System.out.println("Upload HTTP response" + client.getLastResponseCode() + " " + client.getLastResponseMessage());
Here is Javadoc for HttpClient class. The library could be obtained as Maven artifacts or from Github, including source code and Javadoc

Corrupted Json in Android Eclipse

im having a strange problem when receiving json results from the server. I have no idea what the problem is. The thing is that my String json result is corrupted, with strange symbols.
The result is like this (taken from eclipse debug)
Image :
Another strange thing that happens is that when I change the URL of the service to an alternative one, it works and the data is not corrupted. The URLs are the same but once redirects everything to the other.
The URL is use always is (example) http://www.hello.com
The URL that works is http://www.hello.com.uy
(cant post the exact link for security reasons)
The second one redirects everything to the first one, its the only thing it does.
I have tried changing the encoding to UTF-8 and it is still not working, here is the code (with one of the URLs commented)
I have also tried using Dev HTTP Client extension from chrome to check the service and it works fine, no corrupted data. Also, it works perfectly on iOS so i think its just and android/java issue.
DevClient:
try {
JSONObject json = new JSONObject();
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 10000);
HttpConnectionParams.setSoTimeout(httpParams, 10000);
HttpClient client = new DefaultHttpClient(httpParams);
//String url = TAG_BASEURL_REST +"Sucursal";
String url = "http://www.-------.com/rest/Sucursal";
//String url = "http://www.--------.com.uy/rest/Sucursal";
HttpGet request = new HttpGet(url);
request.setHeader("Accept", "application/json");
request.setHeader("Content-type", "application/json");
HttpResponse response = client.execute(request);
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream is = entity.getContent();
BufferedReader reader = new BufferedReader(
new InputStreamReader(is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
String jsonRes = sb.toString();
JSONArray jObj = new JSONArray(jsonRes);
return jObj;
}
} catch (Throwable t) {
Log.i("Error", "Request failed: " + t.toString(), t);
}
return null;
InputStream is = entity.getContent();
// check if the response is gzipped
Header encoding = response.getFirstHeader("Content-Encoding");
if (encoding != null && encoding.getValue().equals("gzip")) {
is = new GZIPInputStream(is);
}

Android Download Zip (That can change name on the server)

I'm trying to make android download a zip file from my web server using a php page to download it.
If I download using a static link to the zip file, it works great, but i'm trying to download using a php file with this code:
function file_list($d,$x){
foreach(array_diff(scandir($d,1),array('.','..')) as $f)if(is_file($d.'/'.$f)&&(($x)?ereg($x.'$',$f):1))$l[]=$f;
return $l;
}
$arr = file_list("../download/",".zip");
$filename = $arr[0];
$filepath = "../download/".$arr[0];
if(!file_exists($filepath)){
die('Error: File not found.');
} else {
// Set headers
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=$filename");
header("Content-Type: application/zip");
header("Content-Transfer-Encoding: binary");
readfile($filepath);
}
If I access the php file in my browser, it downloads the zip just great!
Now, in the Android side, it downloads like it's supposed but the name of the zip is getZip.php (php file name) and the file size is 22.
This is the code that does the downloading stuff on the Android
int count;
try {
downloadCoords();
URL url = new URL(aurl[0]);
URLConnection conexion = url.openConnection();
conexion.connect();
int lengthOfFile = conexion.getContentLength();
Log.d("ANDRO_ASYNC", "Length of file: " + lengthOfFile);
File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
if(!f.isDirectory()){
f.mkdirs();
}
Uri u = Uri.parse(url.toString());
File uf = new File(""+u);
zipname = uf.getName();
Log.d("ANDRO_ASYNC", "Zipname: " + zipname);
File zipSDCARD = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+zipname);
if(!zipSDCARD.isFile()){
Log.d("zipSDCARD.isFile()","false");
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream("/sdcard/" + zipname);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress(""+(int)((total*100)/lengthOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
}
successDownload = true;
} catch (Exception e) {
successDownload = false;
Log.e("Error","DownloadZip",e);
}
What needs to be done, is getting the zipname correctly and the ziplength too.
Thanks in advance.
Well, I solved it using php to write a link to the zip dynamically to the screen using this script:
function file_list($d,$x){
foreach(array_diff(scandir($d,1),array('.','..')) as $f)if(is_file($d.'/'.$f)&&(($x)?ereg($x.'$',$f):1))$l[]=$f;
return $l;
}
$arr = file_list("../download/",".zip");
$filename = $arr[0];
$filepath = "http://".$_SERVER['SERVER_NAME']."/download/".$arr[0];
print($filepath);
Then on the android, I used a BufferedReader to get the link correctly:
private String getZipURL(){
String result = "";
InputStream is = null;
try{
String url = ZipURL;
HttpPost httppost = new HttpPost(url);
HttpParams httpParameters = new BasicHttpParams();
int timeoutConnection = 3000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
int timeoutSocket = 3000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
DefaultHttpClient httpclient = new DefaultHttpClient(httpParameters);
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
}catch(Exception e){
Log.e("getZipURL", "Error in http connection "+e.toString());
return null;
}
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
result=sb.toString();
return result;
}catch(Exception e){
Log.e("convertZipURL", "Error converting result "+e.toString());
return null;
}
}
It may seem wrong, but it works as I want. I posted the code so I can get a workaround for someone with the same problem. Thanks!

Incomplete content (buffer) of webpage

I want to read the content of a webpage with the following methods, but I only get 60-70 percent of it.
I've tried 2 different methods to read the webpage, both with the same result. I also tried different Urls. I get no errors or timeouts.
What I am doing wrong ?
URL url = new URL(uri.toString());
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try
{
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader br = new BufferedReader(new InputStreamReader(in));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = br.readLine()) != null)
{
sb.append(line + "\n");
}
br.close();
this.content = sb.toString();
}
finally
{
urlConnection.disconnect();
}
AND
HttpGet get = new HttpGet(uri);
HttpClient defaultHttp = new DefaultHttpClient(httpParameters);
HttpResponse response = defaultHttp.execute(get);
StatusLine status = response.getStatusLine();
if(status.getStatusCode() == HttpStatus.SC_OK)
{
HttpEntity entity = response.getEntity();
InputStream stream = entity.getContent();
String encoding = "utf-8";
//long length = entity.getContentLength();
//if(entity.getContentEncoding() != null)
//{
// encoding = entity.getContentEncoding().getValue();
//}
//if(length > 0)
//{
byte[] buffer = new byte[1024];
long read = 0;
do
{
read = stream.read(buffer);
if(read > 0)
{
this.content += new String(buffer, encoding);
}
}while(read > 0);
//}
}
#edit
I've tried it with C# and WinForms. I read the complete html source of that webpage.
With java-android it doesn't work.
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("http://www.kicker.de");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
string content = reader.ReadToEnd();
reader.Close();
response.Close();
the httpurlconnection in apache's util jar has limited the biggest bytes in a response, i couldn't remember the number of it.
But in most of time ,may you use the http conncetion in UI thread , so sometimes it's not safe,and maybe will be killed, you can choose to deal with the http request in a thread but not the UI thread. So I want to know if you do it in the UT thread
I have currently the same Problem. I tried my Code in a simple Java Application and I receive the whole content. But on Android, the Content is incomplete. This Question is now a year old. I guess you have solved it in the meantime. Can you please add your Solution?
Edit:
I wrote the content into a File on my Android Device. The Content was complete!
It seems logcat doesn´t show the complete Output you receive from the Devie.

How do I store an image to disk in Java?

I'm using httpclient to download images from a webpage and I'm trying to save them to disk but not having much luck. I'm using the code below to fetch the image but not sure what needs to be done next to actually get it to disk, the fetch would be on a JPG or a PNG image path... thanks
HttpContext localContext = new BasicHttpContext();
localContext.setAttribute(ClientContext.COOKIE_STORE,HttpClientFetch.emptyCookieStore);
HttpGet httpget = new HttpGet(pPage.imageSrc);
HttpResponse response;
response = httpClient.execute(httpget, localContext);
Header[] headers = response.getAllHeaders();
for(Header h: headers) {
logger.info("HEADERS: "+h.getName()+ " value: "+h.getValue());
}
HttpEntity entity = response.getEntity();
Header contentType = response.getFirstHeader("Content-Type");
byte[] tmpFileData;
if (entity != null) {
InputStream instream = entity.getContent();
int l;
tmpFileData = new byte[2048];
while ((l = instream.read(tmpFileData)) != -1) {
}
}
tmpFileData should now hold the bytes of the jpg from the website.
if (entity != null) {
InputStream instream = entity.getContent();
OutputStream outstream = new FileOutputStream("YourFile");
org.apache.commons.io.IOUtils.copy(instream, outstream);
}
Better use Apache commons-io, then you can just copy one InputStream to one OutputStream (FileOutputStream in your case).
Have a look at FileOutputStream and its write method.
FileOutputStream out = new FileOutputStream("outputfilename");
out.write(tmpFileData);

Categories

Resources