java applet HTTP download file can not work - java

i write simple applet to download file from HTTP URL.
In Eclipse or Netbeans, it 's work well and can download file to d://abc//123.iso on my HDD.
This is my code :
public class download {
public static void saveUrl(final String filename, final String urlString)
throws MalformedURLException, IOException {
BufferedInputStream in = null;
FileOutputStream fout = null;
try {
in = new BufferedInputStream(new URL(urlString).openStream());
fout = new FileOutputStream(filename,true);
final byte data[] = new byte[1024];
int count;
fout.write(data, 0, count);
} finally {
if (in != null) {
in.close();
}
if (fout != null) {
fout.close();
}
}
}
}
public class HelloWorldApplet extends Applet
{
public void paint (Graphics g)
{
g.drawString ("Download file", 25, 50);
String url ="http://downloads.asterisk.org/pub/telephony/asterisk-now/AsteriskNOW-612-current-32.iso";
String file_out = "d:\\abc\\123.iso";
download.saveUrl(file_out, url);
}
}
==========================
But when export to jar file and run with html, browser can creat new file 123.iso on my HDD but the size of this file is always 2 Kbps. i think it do not download anything.
Please help me
Thanks so much
P/s : i try to sign jar file with jarsigner but it does not solve the problem

Although I'm skeptical as to the code above doing anything at all as posted, if even compiling, here's the solution I use for doing automatic update downloads of large (>100 MB) files:
HttpGet httpGet;
RequestConfig requestConfig;
getProxySettings();
//Check to see if there is a proxy availabble.
if (!LicensePreloader.proxyAddr.equals("")) {
requestConfig = RequestConfig.custom()
.setSocketTimeout(5000)
.setConnectTimeout(5000)
.setConnectionRequestTimeout(5000)
.setProxy(new HttpHost(LicensePreloader.proxyAddr, LicensePreloader.proxyPort))
.build();
} else {
//No proxy was available, just use regular internet.
requestConfig = RequestConfig.custom()
.setSocketTimeout(5000)
.setConnectTimeout(5000)
.setConnectionRequestTimeout(5000)
.build();
}
httpGet = new HttpGet(this.remoteUrl);
HttpResponse response;
InputStream remoteContentStream = null;
OutputStream localFileStream = null;
try {
httpGet.setConfig(requestConfig);
response = httpClient.execute(httpGet);
//This builds the content of our file we're downloading.
remoteContentStream = response.getEntity().getContent();
long fileSize = response.getEntity().getContentLength();
File dir = localFile.getParentFile();
dir.mkdirs();
localFileStream = new FileOutputStream(localFile);
//Set the buffer, in our use case, it's always the deafult 8192 bytes.
byte[] buffer = new byte[bufferSize];
int sizeOfChunk;
int amountComplete = 0;
//Simply loop through and download the file in 'chunks'
while ((sizeOfChunk = remoteContentStream.read(buffer)) != -1) {
localFileStream.write(buffer, 0, sizeOfChunk);
amountComplete += sizeOfChunk;
updateProgress(amountComplete, fileSize);
}
return localFile;
} finally {
//Make sure to clean everything up.
try {
if (remoteContentStream != null) {
remoteContentStream.close();
}
if (localFileStream != null) {
localFileStream.close();
}
} catch (IOException ex) {
//If we're here, it's likely because the internet conneciton
//couldn't be established, or it was cut short in the middle.
ex.printStackTrace(System.out);
failed();
}
}
}
This is obviously overkill for your application, and you can probably just forget all the proxy business, but I kept it in there for completeness sake. There are a couple helper methods I didn't include, but again, they're almost all exclusively for proxy handling.
good luck!

You are writing one the first read in the input. You need to write the file until the input is empty.
Try this while in you code
while ((count = in.read(data)) != -1) {
fout.write(data, 0, count);
...
}

Related

Problems downloading extensions using Tomcat

static void copyStream(final InputStream inputStream, final OutputStream outputStream, final Client client) throws IOException {
if (client.getReqType() == ReqType.STREAMING_PARTIAL || client.getRange() != null) {
copyPartialStream(inputStream, outputStream, client);
return;
}
Site site = client.getSite();
Qos qos = new Qos(site);
String siteId = site.getSiteId();
byte[] buff = new byte[BUFF_SIZE]; // 1024*32
int readBytes = 0;
try (BufferedInputStream is = new BufferedInputStream(inputStream, BUFF_SIZE)) {
try (BufferedOutputStream out = new BufferedOutputStream(outputStream, BUFF_SIZE)) {
while ((readBytes = is.read(buff)) > -1) {
long startChunk = System.currentTimeMillis();
out.write(buff, 0, readBytes);
client.addSendSize(readBytes);
KHttp.increaseTrafficLog(siteId, readBytes);
long elapsedChunk = System.currentTimeMillis() - startChunk;
client.addSendMils(elapsedChunk);
if (qos.pause(client)) {
long sleepMillis = qos.getSleepMillis(client, readBytes, elapsedChunk);
if (sleepMillis > 0) {
qos.sleep(sleepMillis);
client.addSendMils(sleepMillis);
}
}
}
}
} catch (IOException e) {
client.setAbort(true);
}
}
I am looking at code that provides a link to receive a file using Tomcat. However, if the extension is attached, an error occurs. Not all extensions, but only when the mp3 extension is attached, it is downloaded normally, and when other extensions are attached, an error occurs. It works even if there is no extension at all. I think there is a problem with this code. I hope you can tell me if there is any code with errors. :(

how to download large files chunk by chunk using large files using angular.js and java

We have web application with client in agnular.js and server in java spring. I am working on functionality of downloading this log file i.e. logs.tar from client.
Currently we are using blob to download. Our issue is in case this log size becomes huge like greater than 2GB then while streaming it will create load on application memory. so i want way to download large files chunk by chunk and not required to load entire blob into memory. please suggest way out.
Server side java code -
public ResponseEntity<?> downloadLogs(HttpServletRequest request) {
File file = preferencesService.downloadLogs();
if (file != null) {
FileInputStream inputStream;
try {
inputStream = new FileInputStream(file);
byte[] content = FileCopyUtils.copyToByteArray(inputStream);
String filename = "com-logs.tar";
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + filename);
responseHeaders.add(HttpHeaders.CONTENT_TYPE, "application/octet-stream"
);
return new ResponseEntity<byte[]>(content, responseHeaders, HttpStatus.OK);
} catch (Exception e) {
logger.error("Error while processing log file for download", e);
}
} else {
logger.error("Failed to download logs");
}
return ResponseEntity.badRequest().build();
}
Client side Angular.js code -
this._service.downloadLogs().subscribe(
success => {
var blb = new Blob([success], { 'type': "application/octet-stream" });
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blb, 'logs.tar');
}
else {
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blb);
link.download = "logs.tar";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
});
New Server side java code -
public void downloadLogs(HttpServletResponse resonse) {
File file = preferencesService.downloadLogs(id);
if (file != null) {
try {
resonse.setContentType("application/octet-stream");
resonse.setHeader("Content-Disposition", "attachment;filename=" + file.getName());
BufferedInputStream inStrem = new BufferedInputStream(new FileInputStream(file));
BufferedOutputStream outStream = new BufferedOutputStream(resonse.getOutputStream());
byte[] buffer = new byte[1024];
int bytesRead = 0;
while ((bytesRead = inStrem.read(buffer)) != -1) {
outStream.write(buffer, 0, bytesRead);
}
outStream.flush();
inStrem.close();
}
...
}
The important thing is to not read the file into memory, but to pass the stream on:
public ResponseEntity<?> downloadLogs(HttpServletRequest request) {
File file = preferencesService.downloadLogs();
if (file != null) {
try (InputStream inputStream = Files.newInputStream(file.toPath())) {
InputStreamResource inputStreamResource =
new InputStreamResource(new inputStream);
HttpHeaders responseHeaders = new HttpHeaders();
//responseHeaders.setContentLength(Files.size(file.toPath()));
responseHeaders.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename="
+ filename);
responseHeaders.add(HttpHeaders.CONTENT_TYPE, "application/octet-stream");
return new ResponseEntity(inputStreamResource, responseHeaders, HttpStatus.OK);
}
}
...
}
Consider compression as this will hugely speed things up and cause less server load.
Chunking, setting content length, deflate compression web filters, and so on should be looked into.

refresh servlet jetty java

I have a video stream from an ip-camera and I want to handle this stream via a Server so i can display it on as many devices (like iPads / Browsers) as I need (camera only has 100Mbit/s so a lot of the devices don't show anything). I have a jetty http-Server running. I wrote a class which gets the stream and converts it to a MjpegFrame:
MjpegFrame = frame;
try {
MjpegInputStream m = new MjpegInputStream(url.openStream());
MjpegFrame f;
while ((f = m.readMjpegFrame()) != null) {
if(!running) break;
frame = f;
}
m.close();
} catch (IOException e) {
//some error outputs
}
get the current frame
public MjpegFrame getCurrentFrame() {
return frame;
}
This works fine. Now I am trying to display it with my Servlet, but here I only get a single photo instead of a stream:
protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//String auth = request.getAuthType();
//System.out.println("auth:"+auth);
if(vm != null) {
MjpegFrame frame = vm.getCurrentFrame();
if(frame != null) {
BufferedOutputStream output = null;
try{
output = new BufferedOutputStream(response.getOutputStream(), 1024);
response.reset();
response.setBufferSize(1024);
response.setContentType("image/webp");
response.setHeader("Cache-Control", "max-age=0") ;
response.setHeader("Accept-Encoding", "gzip, deflate, sdch");
while(frame != null){
response.setContentLength(frame.getContentLength());
output.write(frame.getJpegBytes(), 0, frame.getContentLength());
frame = vm.getCurrentFrame();
}
}catch(Exception e){
e.printStackTrace();
}finally {
}
} else {
System.out.println("No image available...");
}
} else {
System.out.println("Error: VideoMultiplier is not set");
}
}
Does anyone know what is wrong with my code?
Solved it by myself:
the problem was the Conent-Type
response.setContentType("image/webp");
I used wireshark to analyse it and realised the response should look different. Anyway, thats my response:
String contentType = "multipart/x-mixed-replace; boundary=--yourboundary";
response.setContentType(contentType);
and instead of --yourboundary you use the boundary from the camera, or, to make it more flexible, build your own header:
public StringBuffer createHeader(int contentLength) {
StringBuffer header = new StringBuffer(100);
header.append("--yourboundary\r\nContent-Type: image/jpeg\r\nContent-Length: ");
header.append(contentLength);
header.append("\r\n\r\n");
return header;
}
and then write it like this:
frame = vm.getCurrentFrame();//here I get my frame of the current image I wanna send
StringBuffer header = createHeader(frame.getJpegBytes().length);
byte[] headerBytes = header.toString().getBytes();
byte[] imageBytes = frame.getJpegBytes();
// create a newImage array that is the size of the two arrays
byte[] newImage = new byte[headerBytes.length + imageBytes.length];
// copy headerBytes into start of newImage (from pos 0, copy headerBytes.length bytes)
System.arraycopy(headerBytes, 0, newImage, 0, headerBytes.length);
// copy imageBytes into end of newImage (from pos headerBytes.length, copy imageBytes.length bytes)
System.arraycopy(imageBytes, 0, newImage, headerBytes.length, imageBytes.length);
output.write(newImage,0,newImage.length);
output.flush();
hope it helps someone.
cheers

How to download a file and get the path location locally

I have a URL i.e http://downloadplugins.verify.com/Windows/SubAngle.exe .
If I paste it on the tab and press enter then the file (SubAngle.exe) is getting downloaded and saved in the download folder. This is a manual process. But it can be done with java code.
I wrote the code for getting the absolute path with the help of the file name i.e SubAngle.exe.
Requirement:- With the help of the URL file gets downloaded,Verify the file has been downloaded and returns the absolute path of the file.
where locfile is "http://downloadplugins.verify.com/Windows/SubAngle.exe"
public String downloadAndVerifyFile(String locfile) {
File fileLocation = new File(locfile);
File fileLocation1 = new File(fileLocation.getName());
String fileLocationPath = null;
if(fileLocation.exists()){
fileLocationPath = fileLocation1.getAbsolutePath();
}
else{
throw new FileNotFoundException("File with name "+locFile+" may not exits at the location");
}
return fileLocationPath;
}
easy and general function that im using:
import org.apache.commons.io.FileUtils;
public static void downLoadFile(String fromFile, String toFile) throws MalformedURLException, IOException {
try {
FileUtils.copyURLToFile(new URL(fromFile), new File(toFile), 60000, 60000);
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("exception on: downLoadFile() function: " + e.getMessage());
}
}
Instead of writing this huge code, go for Apache's commons.io
Try this:
URL ipURL = new URL("inputURL");
File opFile = new File("outputFile");
FileUtils.copyURLToFile(ipURL, opFile);
Code to DownloadFile from URL
import java.net.*;
import java.io.*;
public class DownloadFile {
public static void main(String[] args) throws IOException {
InputStream in = null;
FileOutputStream out = null;
try {
// URL("http://downloadplugins.verify.com/Windows/SubAngle.exe");
System.out.println("Starting download");
long t1 = System.currentTimeMillis();
URL url = new URL(args[0]);
// Open the input and out files for the streams
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
in = conn.getInputStream();
out = new FileOutputStream("YourFile.exe");
// Read data into buffer and then write to the output file
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
long t2 = System.currentTimeMillis();
System.out.println("Time for download & save file in millis:"+(t2-t1));
} catch (Exception e) {
// Display or throw the error
System.out.println("Erorr while execting the program: "
+ e.getMessage());
} finally {
// Close the resources correctly
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
}
Configure the value of fileName properly to know where the file is getting stored.
Source: http://www.devmanuals.com/tutorials/java/corejava/files/java-read-large-file-efficiently.html
The source was modified to replace local file with http URL
Output:
java DownloadFile http://download.springsource.com/release/TOOLS/update/3.7.1.RELEASE/e4.5/springsource-tool-suite-3.7.1.RELEASE-e4.5.1-updatesite.zip
Starting download
Time for download & save file in millis:100184

Trouble with uploading a file from an applet to servlet

I am working on an applet that records voice and uploads to a servlet.
Here is the code of the upload thread in the applet
class uploadThread extends Thread {
#Override
public void run() {
try {
//Preparing the file to send
AudioFileFormat.Type fileType = AudioFileFormat.Type.WAVE;
File file = File.createTempFile("uploded", ".wav");
byte audio[] = out.toByteArray();
InputStream input = new ByteArrayInputStream(audio);
final AudioFormat format = getFormat();
final AudioInputStream ais = new AudioInputStream(input, format, audio.length / format.getFrameSize());
AudioSystem.write(ais, fileType, file);
//uploading to servlet
FileInputStream in = new FileInputStream(fileToSend);
byte[] buf = new byte[1024];
int bytesread = 0;
String toservlet = "http://localhost:8080/Servlet/upload";
URL servleturl = new URL(toservlet);
URLConnection servletconnection = servleturl.openConnection();
servletconnection.setDoInput(true);
servletconnection.setDoOutput(true);
servletconnection.setUseCaches(false);
servletconnection.setDefaultUseCaches(false);
DataOutputStream out = new DataOutputStream(servletconnection.getOutputStream());
while ((bytesread = in.read(buf)) > -1) {
out.write(buf, 0, bytesread);
}
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
System.err.println("Error during upload");
}
}
}//End of inner class uploadThread
Here is the code of the grab file method in the servlet:
java.io.DataInputStream dis = null;
try {
int fileLength = Integer.valueOf(request.getParameter("fileLength"));
String fileName = request.getParameter("fileName");
dis = new java.io.DataInputStream(request.getInputStream());
byte[] buffer = new byte[fileLength];
dis.readFully(buffer);
dis.close();
File cibleServeur = new File("/Users/nebrass/Desktop/" + fileName);
FileOutputStream fos = new FileOutputStream(cibleServeur);
fos.write(buffer);
fos.close();
} catch (IOException ex) {
Logger.getLogger(UploadServlet.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
dis.close();
} catch (Exception ex) {
Logger.getLogger(UploadServlet.class.getName()).log(Level.SEVERE, null, ex);
}
}
I have created a certificate with the keytool. And i have signed the JAR of the applet.
I have added the applet to the jsp file and it is working, and have the all permissions (I tried to save a file on a desktop using the applet)
Update: The problem is that the file is not sent, and when i try to debug the servlet, it is not invoked by the the applet.
Please help
That's not how it works. You've just opened a URLConnection and wrote to the output stream. That way you're assuming something like a socket connection, but here we need more of a HttpUrlConnection and then a request-parameter and a multi-part request.
Google Search
Google found lots of solutions, but for the completeness of the answer, I'm adding one below :
https://stackoverflow.com/a/11826317/566092
You want up upload a file from the server to the user desktop?
I doubt this will be allowed, for obvious security reasons.
Why don't you just call the servlet directly from the browser? And "save as" the file?
Here is an exemple on how to send a file (any type) from a servlet.
protected void doPost(
...
response.setContentType("your type "); // example: image/jpeg, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/octet-stream
response.setHeader("Content-Disposition","attachment; filename=\"your_filename\"");
File uploadedFile = new File("/your_file_folde/your_file_name");
if (uploadedFile.exists()){
FileUtils.copyFile(uploadedFile, response.getOutputStream());
}
else { // Error message
}
....
}

Categories