1

I am trying to send a zip file from a Java servlet to a JavaScript client. I first generate the zip archive on the disk, and then I try to send it to the client. The zip generation works fine. However, I have a problem with sending it to the client.

The code related to sending the file to the client (inside doPost) is the following:

  String path = getServletContext().getRealPath("/") + "generatedApps/";     
  String fileName = appName + "Archive.zip";
  File f = new File(path + fileName);       

  response.setContentType("application/zip");     
  response.setContentLength((int)f.length());  
  response.addHeader("Content-Encoding", "gzip"); 
  response.addHeader("Content-Disposition","attachment;filename=\"" + fileName + "\"");    
  byte[] arBytes = new byte[(int)f.length()];     
  FileInputStream is = new FileInputStream(f);     
  is.read(arBytes);     
  ServletOutputStream op = response.getOutputStream();     
  op.write(arBytes);     
  op.flush();    

This is the Ajax request from the client:

new Ajax.Request( source, {
  asynchronous: false,
  method: 'post',
  parameters: {content: RWSMLFile},
  onSuccess: function(transport){                   
    console.log(transport);
  }.bind(this),
  onFailure: (function ( transport ) {
    ORYX.Log.error( "Sending RWSML file failed! Info: " + transport );
  }).bind( this )
} );

In the browser console I get the following error:

POST http://localhost:8080/oryx/generategeddyjscode  prototype-1.5.1.js:1044
  Ajax.Request.Object.extend.request prototype-1.5.1.js:1044
  Ajax.Request.Object.extend.initialize prototype-1.5.1.js:1006
  (anonymous function) prototype-1.5.1.js:37
  ORYX.Plugins.RWSMLSupport.ORYX.Plugins.AbstractPlugin.extend.generateGeddyJsCode rwsmlSupport.js:47
  (anonymous function) prototype-1.5.1.js:105
  a.each.j.functionality default.js:2828
  Ext.Button.Ext.extend.onClick ext-all.js:87
  V ext-all.js:13
  O

If I go to the Source tab, then I get Failed to load resource after the last line of the following code snippet:

  if (this.options.onCreate) this.options.onCreate(this.transport);
  Ajax.Responders.dispatch('onCreate', this, this.transport);

  this.transport.open(this.method.toUpperCase(), this.url,
    this.options.asynchronous);

  if (this.options.asynchronous)
    setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10);

  this.transport.onreadystatechange = this.onStateChange.bind(this);
  this.setRequestHeaders();

  this.body = this.method == 'post' ? (this.options.postBody || params) : null;
  this.transport.send(this.body);

How can I solve the problem?

1 Answers1

4

You need to check how many bytes have been written using the return code FileInputStream.read(). Try something like this:

  String path = getServletContext().getRealPath("/") + "generatedApps/";     
  String fileName = appName + "Archive.zip";
  File f = new File(path + fileName);       

  response.setContentType("application/zip");     
  response.setContentLength((int)f.length());  
  response.addHeader("Content-Disposition","attachment;filename=\"" + fileName + "\"");    
  byte[] arBytes = new byte[32768];     
  FileInputStream is = new FileInputStream(f);
  ServletOutputStream op = response.getOutputStream();     
  int count;
  while ((count = is.read(arBytes)) > 0)
  {
      op.write(arBytes, 0, count);     
  }
  op.flush();    

Edit:

Removed response.addHeader("Content-Encoding", "gzip"); copied from the question. It is just wrong.

HHK
  • 4,852
  • 1
  • 23
  • 40
  • Ahh also remove this line: `response.addHeader("Content-Encoding", "gzip");` – HHK Jun 20 '14 at 17:50
  • ok, I'm receiving something... `PK���D(MyApp/app/controllers/ObjectTypeNames[...]`... I suppose this weird string is the result of the fact that a zip file cannot be displayed in the `response` field... am I right?... and do you also know how to download the received file? – Sorin Adrian Carbunaru Jun 20 '14 at 18:43
  • actually want I wanted to accomplish was to download a zip file generated by the servlet and, although I read that this can't be done with Ajax, I thought that maybe there is a simple way to construct the file in the client from the result sent by the servlet... in the end I dropped the Ajax call and replaced it with a form... this works and I can download my file... thank you for helping me sending the file – Sorin Adrian Carbunaru Jun 21 '14 at 06:46