Hello All,
I'm posting for the first time, so please inform me if I do something wrong ...
First of all - problem description :
I have application in multilanguage (where user can dynamically change charset).
Problem rises when user enters information in selected language.
After parsePostData in HttpUtils I get lots of "????" instead of text.
I can not rely on default system encoding, because application has ability to add the
languages dynamically without recompilation.
So I never know what next encoding system will need.
I have written some code to work around this problem and think it would be nice to
have it standard package.
Actually I've changed parsePostData - added encoding parameter.
Now programmer could choose in what encoding InputStream is supplied.
I have tested it with windows-1257 (Baltic) and windows-1251 (Cyrylic) - for me it
worked.
If someone find any errors - please let me know.
Here is code of that method :
////////////////////////////////////////////////////////////////////////////////
// Parses data from an HTML form that the client sends to
// the server using the HTTP POST method and the
// <i>application/x-www-form-urlencoded</i> MIME type.
//
// <p>The data sent by the POST method contains key-value
// pairs. A key can appear more than once in the POST data
// with different values. However, the key appears only once in
// the hashtable, with its value being
// an array of strings containing the multiple values sent
// by the POST method.
//
// <p>The keys and values in the hashtable are stored in their
// decoded form, so
// any + characters are converted to spaces, and characters
// sent in hexadecimal notation (like <i>%xx</i>) are
// converted to specified encoding.
//
// @param len an integer specifying the length,
// in characters, of the
// <code>ServletInputStream</code>
// object that is also passed to this
// method
// @param in the <code>ServletInputStream</code>
// object that contains the data sent
// from the client
// @param enc a String specifying the character encoding
// of the <code>ServletInputStream</code>
// object
//
// @return a <code>HashTable</code> object built
// from the parsed key-value pairs
//
// @exception IllegalArgumentException if the data
// sent by the POST method is invalid
////////////////////////////////////////////////////////////////////////////////
public Hashtable parsePostData (int len, ServletInputStream in, String enc)
{
// XXX
// should a length of 0 be an IllegalArgumentException
if (len <=0)
return new Hashtable (); // cheap hack to return an empty hash
if (in == null) {
throw new IllegalArgumentException ();
}
// Make sure we read the entire POSTed body.
byte [] postedBytes = new byte [len];
try {
int offset = 0;
do {
int inputLen = in.read (postedBytes, offset, len - offset);
if (inputLen <= 0) {
throw new IllegalArgumentException
(lStrings.getString("err.io.short_read"));
}
offset += inputLen;
} while ((len - offset) > 0);
}
catch (IOException e) {
throw new IllegalArgumentException (e.getMessage ());
}
// Here some changes ...
// Direct parsing of postedBytes, converting to
// desired unicode symbol and forming final string
StringBuffer sb = new StringBuffer ();
Integer unicodeInteger;
for (int i = 0; i < postedBytes.length - 1; i++) {
String testString = new String (postedBytes, i, 1);
switch (testString.charAt (0)) {
case '+' :
sb.append (' ');
break;
case '%' :
try {
// Here is actual conversion to unicode
unicodeInteger = Integer.valueOf (new String
(postedBytes, i + 1, 2), 16);
sb.append (new String (new byte []
{unicodeInteger.byteValue ()}, enc));
i += 2;
}
catch (NumberFormatException e) {
throw new IllegalArgumentException ();
}
catch (UnsupportedEncodingException e) {
throw new IllegalArgumentException ();
}
catch (ArrayIndexOutOfBoundsException e) {
// This can happen only at the end of stream
// So just add the rest and stop loop
String rest = new String (postedBytes, i,
postedBytes.length - i);
sb.append (rest);
i += rest.length ();
}
break;
default:
// Here do not use encodintg
// It is expected, that request is sent in
sb.append (new String (postedBytes, i, 1));
break;
}
}
return (parseQueryString (sb.toString ()));
}
Best regards,
Aleksandras Novikovas [EMAIL PROTECTED]
IT manager
Baltic Logistic System Vilnius Ltd.
Kirtumu 51, Vilnius, Lithuania
Phone: +370-2-390874; FAX: +370-2-390899; Mobile: +370-99-21678