JDK-4449371 : URLEncoder and URLDecoder requires encoding support other than the default one
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 1.0
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic
  • CPU: generic
  • Submitted: 2001-04-23
  • Updated: 2001-04-23
  • Resolved: 2001-04-23
Related Reports
Duplicate :  
Description

Name: mt13159			Date: 04/23/2001


This is not a JDK version specific bug.

URLEncoder.encode(String s) method and URLDecoder.decode(String s) method
provide functionality to encode/escape URL parameters based on RFC2396
section 2.4. The problem in these two methods in these classes they use
the default encoding of java runtime environment. HTML appliations
usually have to deal with variety of character encodings in HTTP requests
and responses.
As a result, these classes are unusable in real world and also causes
a lot of problems in other java and servlet/jsp classes that use this
method.
I'd like to request Sun to provide following addition methods for both
classes.

java.net.URLEncoder
    public static String encode(String s, String enc)

java.net.URLDecoder
    public static String decode(String s, String enc)

'String s' is the string need to be encoded and decoded.
'String enc' is the encoding name that be used to encode and
decode.

I put enhanced URLEncoder and URLDecoder classes in Work Around
section. Please see.
(Review ID: 121149) 
======================================================================

Comments
EVALUATION This functionality is planned for 1.4 See 4257115.
11-06-2004

WORK AROUND Name: mt13159 Date: 04/23/2001 ------------------------------------------- An enhanced version of java.net.URLEncoder ------------------------------------------- import java.io.*; import java.util.*; /** * This class is an enhanced version of java.net.URLEncoder class. * This enhancement enable you to specify a character encoding * for URL string before encoding URL string. * See java.net.URLEncoder for generic Usage of URL encoding. */ public class URLEncoder { // list "unreserved" set in RFC 2396. Other characters not listed in // here are be escaped with "%" hex hex. static String unreserved = new String("-_.!~*'() ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz 0123456789"); static int caseUpper = ('a' - 'A'); /** * Translates a string into <code>x-www-form-urlencoded</code> format. * JVM's default encoding is used. * * @param s <code>String</code> to be translated. * @return the translated <code>String</code>. */ public static String encode(String s) { return java.net.URLEncoder.encode(s); } /** * Translates a string into <code>x-www-form-urlencoded</code> format. * * @param s <code>String</code> to be translated. * @param enc Name of the encoding to be used. * @return the translated <code>String</code>. */ public static String encode(String s, String enc) { StringBuffer out = new StringBuffer(s.length()); ByteArrayOutputStream buf = new ByteArrayOutputStream(); OutputStreamWriter writer; try { writer = new OutputStreamWriter(buf, enc); } catch (UnsupportedEncodingException e) { // use JVM's default encoding writer = new OutputStreamWriter(buf); } for (int i = 0; i < s.length(); i++) { int c = (int)s.charAt(i); if (unreserved.indexOf(c) != -1) { if (c == ' ') { c = '+'; } out.append((char)c); } else { // convert a character to the specified encoding // before hex conversion try { writer.write(c); writer.flush(); } catch(IOException e) { buf.reset(); continue; } byte[] ba = buf.toByteArray(); for (int j = 0; j < ba.length; j++) { out.append('%'); char ch = Character.forDigit((ba[j] >> 4) & 0xF, 16); if (Character.isLetter(ch)) { ch -= 'a' - 'A'; } out.append(ch); ch = Character.forDigit(ba[j] & 0xF, 16); if (Character.isLetter(ch)) { ch -= caseUpper; } out.append(ch); } buf.reset(); } } return out.toString(); } } ------------------------------------------- A Enhanced version of java.net.URLDecoder ------------------------------------------- import java.io.*; /** * This class is an enhanced version of java.net.URLDecoder class. * This enhancement enable you to specify a correct character encoding * used in an encoded URL string. * See java.net.URLDecoder for generic Usage of URL decoding. */ public class URLDecoder { public static String decode(String s) { String encoding = System.getProperty("file.encoding", "8859_1"); return decode(s, encoding); } public static String decode(String s, String encoding) { StringBuffer sbout = new StringBuffer(); StringBuffer sb = new StringBuffer(); boolean inUnicode = false; String enc = encoding; for(int i=0; i<s.length(); i++) { char c = s.charAt(i); switch (c) { case '+': if (inUnicode == true) { flush(sb, sbout, enc); sb = new StringBuffer(); inUnicode = false; } enc = encoding; sb.append(' '); break; case '%': if (s.charAt(i+1) != 'u') { if (inUnicode == true) { flush(sb, sbout, enc); sb = new StringBuffer(); inUnicode = false; } enc = encoding; try { sb.append((char)Integer.parseInt( s.substring(i+1,i+3),16)); i += 2; } catch (NumberFormatException e) { throw new IllegalArgumentException(); } catch (StringIndexOutOfBoundsException e) { String rest = s.substring(i); sb.append(rest); if (rest.length()==2) i++; } break; } else { if (inUnicode == false) { flush(sb, sbout, enc); sb = new StringBuffer(); inUnicode = true; } try { sb.append((char)Integer.parseInt( s.substring(i+2,i+4),16)); sb.append((char)Integer.parseInt( s.substring(i+4,i+6),16)); } catch (NumberFormatException e) { throw new IllegalArgumentException(); } i += 5; enc = "UnicodeBig"; break; } default: if (inUnicode == true) { flush(sb, sbout, enc); sb = new StringBuffer(); inUnicode = false; } enc = encoding; sb.append(c); break; } } flush(sb, sbout, enc); return sbout.toString(); } private static void flush(StringBuffer sb, StringBuffer sbout, String encoding) { // Undo conversion to external encoding String result = sb.toString(); byte [] inputBytes; try { inputBytes = result.getBytes("8859_1"); } catch (UnsupportedEncodingException e) { // use JVM's default encoding // I don't expect program go through here. inputBytes = result.getBytes(); } try { sbout.append(new String(inputBytes, encoding)); } catch (UnsupportedEncodingException e) { // use JVM's default encoding sbout.append(new String(inputBytes)); } } } ======================================================================
11-06-2004