You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Paritosh Patel <xy...@gmail.com> on 2011/07/15 17:23:53 UTC

How to send binary data in a form field via Java

I apologize in advance if this is not the correct mail list for such a question, but this is the closest one I could find. 

(I am using Tomcat 6.0.26 but my question is generic in nature)

I have a Java client that talks to a servlet using several text fields. I now wanted to add a field that includes binary data (in this case a protocol buffer byte array). The data gets to the servlet, but the bytes are changed. Specifically, it appears that the encoding/decoding of bytes > 127 are not the same as the original bytes.

The client specified content-type to be "application/x-www-form-urlencoded" right now, but I have tried several others. Then, for encoding, I have tried encoding the bytes using URLEncoder

	ByteArrayOutputStream osBytes = new ByteArrayOutputStream();
	byte[] val = "..."  // My binary data
	String valStr = new String((byte[]) val);
	osBytes.write(URLEncoder.encode(valStr, "UTF-8").getBytes());

	DataOutputStream  os = new DataOutputStream(urlConn.getOutputStream());
	os.write(osBytes.toByteArray());

Now, on the servlet side, I do a request.getParameter() to get the field. It is already decoded (I assume URL decoding) by the servlet container. Do I have control over the decoding?

A portion of the byte array at the client is as follows...
31 12  e  8 ac e2 cb 8c 90 26 10 90

There are several variables, that I need to get right at the same time.
1) content-type... what is the correct content type
2) encoder... is URLEncoder the correct encoder?
3) encode string... UTF-8 and US-ASCII do not work. 
4) do I have control over the decoding on the servlet side?
5) anything else I need to worry about?

Any help would be greatly appreciated.

- Tosh


Re: How to send binary data in a form field via Java

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Paritosh,

On 7/15/2011 11:23 AM, Paritosh Patel wrote:
> The client specified content-type to be 
> "application/x-www-form-urlencoded" right now, but I have tried
> several others.

Note that application/x-www-form-urlencoded requires that you properly
set the "Content-Type" header with an appropriate "charset" parameter.
Are you doing that? If not, your stuff will break.

> Then, for encoding, I have tried encoding the bytes using URLEncoder
> 
> ByteArrayOutputStream osBytes = new ByteArrayOutputStream(); byte[]
> val = "..."  // My binary data String valStr = new String((byte[])
> val); osBytes.write(URLEncoder.encode(valStr, "UTF-8").getBytes());

So, a few problems, here. First, new String(byte[]) will destroy your
data because you are not specifying a charset to use. Second, never put
binary data into a String because it's going to end up destroyed.

Second, URLEncoding the string will just make things worse. You don't
need ? changed to %whatever, etc.

> DataOutputStream  os = new
> DataOutputStream(urlConn.getOutputStream()); 
> os.write(osBytes.toByteArray());
> 
> Now, on the servlet side, I do a request.getParameter() to get the 
> field. It is already decoded (I assume URL decoding) by the servlet 
> container. Do I have control over the decoding?

Okay, you're in a giant mess at this point. Instead of continuing to
read what it certainly to be a great tale of tilting at windmills, let
me make two suggestions (pick one):

1. Use base64-encoded values and treat them as strings. The only
   changes would be to base64-encode the value before you
   stick it into the form (where it becomes an ASCII-compatible string)
   and then de-code it in your servlet.

2. Use multipart/form-data and have a separate MIME part that has
   MIME type of application/octet-stream where you dump your raw
   bytes to the binary stream. Note that you can't use a "writer"
   to write this data: you must use an OutputStream.

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk4gnTIACgkQ9CaO5/Lv0PApogCgkSezcapQx+D2i5qW7SI79lAy
aXIAoIZoFUVsI47hU/pSRoZjDGmIxqsM
=3War
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: How to send binary data in a form field via Java

Posted by Thad Humphries <th...@gmail.com>.
If you are sending binary data--say because you user is downloading a file,
or your servlet is writing a image--you need to open a
javax.servlet.ServletOutputStream (
http://download.oracle.com/javaee/6/api/javax/servlet/ServletOutputStream.html
).

On Fri, Jul 15, 2011 at 11:23 AM, Paritosh Patel <xy...@gmail.com> wrote:

> I apologize in advance if this is not the correct mail list for such a
> question, but this is the closest one I could find.
>
> (I am using Tomcat 6.0.26 but my question is generic in nature)
>
> I have a Java client that talks to a servlet using several text fields. I
> now wanted to add a field that includes binary data (in this case a protocol
> buffer byte array). The data gets to the servlet, but the bytes are changed.
> Specifically, it appears that the encoding/decoding of bytes > 127 are not
> the same as the original bytes.
>
> The client specified content-type to be "application/x-www-form-urlencoded"
> right now, but I have tried several others. Then, for encoding, I have tried
> encoding the bytes using URLEncoder
>
>        ByteArrayOutputStream osBytes = new ByteArrayOutputStream();
>        byte[] val = "..."  // My binary data
>        String valStr = new String((byte[]) val);
>        osBytes.write(URLEncoder.encode(valStr, "UTF-8").getBytes());
>
>        DataOutputStream  os = new
> DataOutputStream(urlConn.getOutputStream());
>        os.write(osBytes.toByteArray());
>
> Now, on the servlet side, I do a request.getParameter() to get the field.
> It is already decoded (I assume URL decoding) by the servlet container. Do I
> have control over the decoding?
>
> A portion of the byte array at the client is as follows...
> 31 12  e  8 ac e2 cb 8c 90 26 10 90
>
> There are several variables, that I need to get right at the same time.
> 1) content-type... what is the correct content type
> 2) encoder... is URLEncoder the correct encoder?
> 3) encode string... UTF-8 and US-ASCII do not work.
> 4) do I have control over the decoding on the servlet side?
> 5) anything else I need to worry about?
>
> Any help would be greatly appreciated.
>
> - Tosh
>
>


-- 
"Hell hath no limits, nor is circumscrib'd In one self-place; but where we
are is hell, And where hell is, there must we ever be" --Christopher
Marlowe, *Doctor Faustus* (v, 121-24)

RE: How to send binary data in a form field via Java

Posted by eurotrans-Verlag <ve...@t-online.de>.
Hi,

> -----Original Message-----
> From: Paritosh Patel [mailto:xygnusx1@gmail.com]
> Sent: Friday, July 15, 2011 5:24 PM
> To: users@tomcat.apache.org
> Subject: How to send binary data in a form field via Java
> 
> I apologize in advance if this is not the correct mail list for such a
> question, but this is the closest one I could find.
> 
> (I am using Tomcat 6.0.26 but my question is generic in nature)
> 
> I have a Java client that talks to a servlet using several text fields.
> I now wanted to add a field that includes binary data (in this case a
> protocol buffer byte array). The data gets to the servlet, but the
> bytes are changed. Specifically, it appears that the encoding/decoding
> of bytes > 127 are not the same as the original bytes.

That's expected, because ASCII is only defined to byte 127. From byte 128,
the related characters differ by the used Encoding (UTF-8, ISO-8859-1,...)


> 
> The client specified content-type to be "application/x-www-form-
> urlencoded" right now, but I have tried several others. Then, for
> encoding, I have tried encoding the bytes using URLEncoder
> 
> 	ByteArrayOutputStream osBytes = new ByteArrayOutputStream();
> 	byte[] val = "..."  // My binary data
> 	String valStr = new String((byte[]) val);
> 	osBytes.write(URLEncoder.encode(valStr, "UTF-8").getBytes());

That is unreliable, because the bytes are converted to chars using the
platform's default charset. If that differs from the server's one, the bytes
will be decoded to other characters.


Have you tried to just Hex-encode the bytes when sending it to the server,
and decoding it on the server side? For example, if your byte[] array is {1,
99, 0, 255}, you could encode it to the hex string "016300FF", and then on
the server side, decode it to bytes.

However, a more efficient form would be to encode the bytes via Base64,
which will mean a increase in size of only 33% instead 100% (when
hex-encoding it).


Regards,
Konstantin Preißer


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org