0

In my code (HttpServlet in doGet method) I need to write bytes that can take any value, from 0 to 255, in a .js file. I checked in the debugger that result[1] has the value 0. However, in the external file it is written as blank space and when I try to read it has the byte value "32". I only have this problem with the byte 0, for the rest this is working perfectly. Any ideas?

res.setContentType("image/gif");
res.setHeader("Content-Disposition","attachment;filename=myFile.js");
OutputStream os = res.getOutputStream();
byte[] result=encrypt(req.getParameter("original")); // Here result has values [64,0,81,80]
os.write(result,0,result.length);

I retrieve the values from an external JavaScript:

var whatever = data[1].charCodeAt(0); // whatever has value 32

I have seen a similar problem in a Javascript program, and they fixed this problem including this loop right before writing to file:

for (var i=0; i<result.length; i++) {
    result[i] = String.fromCharCode(result[i]); }

I have do some tests and works for Javascript. What would be the equivalent in Java?

Thanks

  • 2
    Why are you setting content type `image/gif` for a javascript file? – Darin Dimitrov Jan 16 '12 at 08:51
  • Because this JS file can include non-text characters (as this byte 0), and if I use content type "text/javascript" would be a problem, right? Thanks –  Jan 16 '12 at 11:02
  • 1
    javascript is text. I am not aware of any browser that would make sense of javascript containing binary characters. – Darin Dimitrov Jan 16 '12 at 11:04
  • Thanks Darin. Please see my reply to Apurv's comment below ("Let's keep..."). –  Jan 16 '12 at 12:09

3 Answers3

1

32 is the ASCII value for blank space. That is why you are getting blank for 32.

Apurv
  • 3,723
  • 3
  • 30
  • 51
  • Thanks. But why is ASCII 0 written as a blank space? –  Jan 16 '12 at 11:01
  • @user411103 there must be an alternative to what you are doing. Why do you want to include binary data in text file ?\ – Apurv Jan 16 '12 at 11:15
  • Let's keep it simple. Forget it is a .js file. I just want to write in a binary file the ASCII 0 (which is NULL but no BLANK SPACE) and read it as 0 but not 32. What would be wrong in the code above? Thanks –  Jan 16 '12 at 12:08
  • 1
    The problem starts when try to read it with 'charCodeAt'. If you are writing something as a binary data, read it as binary data and not as text – Apurv Jan 16 '12 at 12:16
  • @user411103 Can you try this http://www.codeproject.com/KB/scripting/Exsead7.aspx for reading binary data from JS ? – Apurv Jan 16 '12 at 12:33
  • Thanks Apurv, I will try this code. I agree that I should not use charCodeAt to reade binary data, but I believe that the problem is at write time, as I am comparing the output file to one that I certify is correct, and 0 instead of been written " " (blank space) is "" (null), that is is correct. So why in my code is 0 written as blank space using the OutputStream.write()? –  Jan 16 '12 at 14:09
0

Reading binary data has already been answered in Stackoverflow: How do I read binary data to a byte array in Javascript?.

Content type better is application/octet-stream, without content disposition header.

Community
  • 1
  • 1
Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
  • Thanks for your help. I cannot remove the content-disposition header, because I really need this data displayed as an attachment. Then I tried "application/octet-stream" with the reading binary function, and this is still reading a "32" (blank space) where I see the OutputStream.write function has a "0". I believe this is a writing problem, not reading. Perhaps should I specify somehow the charset for the output file? –  Jan 16 '12 at 23:37
  • I have edited my initial question with something that fixes this problem in Javascript. But I am not sure what to do for Java. –  Jan 17 '12 at 00:19
  • Then the encrypt function must be erroneous, or the original parameter. – Joop Eggen Jan 17 '12 at 02:10
  • Joop, I just tried a very simple example: byte[] result=new byte[3];result[0]=65;result[1]=0;result[2]=66;os.write(result,0,result.length);os.flush();os.close(); And I am receiving [65,32,66], so it is not the encrypt function or parameter. Perhaps the setCharacterEncoding() function? Thanks –  Jan 17 '12 at 08:55
  • Did you try saving it as file in the browser, i.o. reading? os.write has to be okay. Maybe changing the attachment name into something binary. BTW when all works, a `setContentLength` might be added. – Joop Eggen Jan 17 '12 at 13:29
  • Thanks. Something interesting that make me thing it is a charset issue. The same code works when I deployed it in Google App Engine. Another difference between my test server (Eclipse) and GAE: just reading text from an external file, in my test server it is including a "13" byte at the end of the reading buffer, but in GAE not. Any ideas? –  Jan 18 '12 at 08:28
  • Yes the binary data seems to be treated as text; therefore .js is suspicious, as it indicates text. – Joop Eggen Jan 18 '12 at 11:53
  • In GAE I am using .JS as well, and is working. Perhaps a different charset applies by default in that environment for HttpServlet.doPost()? –  Jan 18 '12 at 15:07
0

You can check these

Is there any way to send binary data with XMLHttpRequest object?

Send and receive binary data over web sockets in Javascript?

http://www.codeproject.com/KB/scripting/Javascript_binaryenc.aspx

http://support.microsoft.com/kb/296772

Community
  • 1
  • 1
Apurv
  • 3,723
  • 3
  • 30
  • 51
  • The funny story is that if I deploy this code to Google App Engine, it is working. But it is not in my test server (Eclipse). Perhaps a charset? –  Jan 18 '12 at 08:17
  • Are you saying that your original code is working in Google App Engine ? – Apurv Jan 18 '12 at 08:53
  • That is exactly what I am saying. And working with a JS file as well. Perhaps GAE applies a different charset by default in HttpServlet doGet/doPost?? –  Jan 18 '12 at 15:06