2012-07-10 130 views
1

我有一个数据库中混合数据的情况,我试图看看这是否是一个可以解决的问题。我所拥有的是三种格式之一的部分网址:在Java中检测URL的编码

/some/path?ugly=häßlich // case 1, Encoding: UTF-8 (plain) 
/some/path?ugly=h%C3%A4%C3%9Flich // case 2, Encoding: UTF-8 (URL-encoded) 
/some/path?ugly=h%E4%DFlich // case 3: Encoding: ISO-8859-1 (URL-encoded) 

我需要在我的应用程序是URL编码UTF8版本

/some/path?ugly=h%C3%A4%C3%9Flich // Encoding: UTF-8 (URL-encoded) 

颖在DB都是UTF- 8,但是URL编码可能存在也可能不存在,并且可能具有任何一种格式。

我有一个方法a编码简单的UTF-8 URL编码UTF-8,和我有一个方法b解码URL编码ISO-8859-1为纯UTF-8,所以基本上是我计划做的是:

壳体1:

String output = a(input); 

壳体2:

String output = input; 

壳体3:

String output = a(b(input)); 

所有这些情况下工作正常,如果我知道哪个是哪个,但有没有一种安全的方式来检测这样的字符串是否是情况2或3? (我可以将参数中使用的语言限制为欧洲语言:德语,英语,法语,荷兰语,波兰语,俄语,丹麦语,挪威语,瑞典语和土耳其语,如果有任何帮助的话)。

我知道显而易见的解决方案是清理数据,但不幸的是,数据不是由我自己创建的,也不是具有必要技术理解的人员(并且有大量需要工作的遗留数据)

+0

只是字符(如你的例子)和数字编码? – s106mo 2012-07-10 20:24:08

+0

@ s106mo是的,应用程序是一个重定向到一个更好的搜索查询。而那些按照定义是字母数字。感谢您的建议 – 2012-07-10 21:21:42

回答

2

如果你可以假设,只有字母数字编码,以下woud的工作:

  • “häßlich”
  • “H%C3%A4%C3%9Flich”
  • “H%E4 %DFlich“

//检查首先:

public static boolean isUtf8Encoded(String url) { 
    return isAlphaNumeric(url); 
} 

public static boolean isUrlUtf8Encoded(String url) 
     throws UnsupportedEncodingException { 
    return isAlphaNumeric(URLDecoder.decode(url, "UTF-8")); 
} 

public static boolean isUrlIsoEncoded(String url) 
     throws UnsupportedEncodingException { 
    return isAlphaNumeric(URLDecoder.decode(url, "ISO-8859-1")); 
} 

private static boolean isAlphaNumeric(String decode) { 
    for (char c : decode.toCharArray()) { 
     if (!Character.isLetterOrDigit(c)) { 
      return false; 
     } 
    } 
    return true; 
} 
0

感谢接受的答案,但它并不适用于URL工作,因为URL还包含控制字符,这是我的解决方案:

/** 
* List of valid characters in URL. 
*/ 
private static final List VALID_CHARACTERS = Arrays.asList(
     '-', '.', '_', '~', ':', '/', '?', '#', '[', ']', '@', '!', 
     '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=' 
); 

/** 
* Check that decoding was successful or not. 
* @param url URL to check 
* @return True if it's valid. 
*/ 
private static boolean isMalformed(final String url) { 
    for (char c : url.toCharArray()) { 
     if (VALID_CHARACTERS.indexOf(c) == -1 && !Character.isLetterOrDigit(c)) { 
      return false; 
     } 
    } 
    return true; 
} 

/** 
* Try to decode URL with specific encoding. 
* @param url URL 
* @param encoding Valid encoding 
* @return Decoded URL or null of encoding is not write 
* @throws java.io.UnsupportedEncodingException Throw if encoding does not support on your system. 
*/ 
private static String _decodeUrl(final String url, final String encoding) { 
    try { 
     final String decoded = URLDecoder.decode(url, encoding); 
     if(isMalformed(decoded)) { 
      return decoded; 
     } 
    } 
    catch (UnsupportedEncodingException ex) { 
     throw new IllegalArgumentException("Illegal encoding: " + encoding); 
    } 
    return null; 
} 

/** 
* Decode URL with most popular encodings for URL. 
* @param url URL 
* @return Decoded URL or original one if encoding does not support. 
*/ 
public static String decodeUrl(final String url) { 
    final String[] mostPopularEncodings = new String[] {"iso-8859-1", "utf-8", "GB2312"}; 
    return decodeUrl(url, mostPopularEncodings); 
} 

/** 
* Decode URL with most popular encodings for URL. 
* @param url URL 
* @param encoding Encoding 
* @return Decoded URL or original one if encoding does not support. 
*/ 
public static String decodeUrl(final String url, final String... encoding) { 
    for(String e:encoding) { 
     final String decoded; 
     if((decoded = _decodeUrl(url, e)) != null) { 
      return decoded; 
     } 
    } 
    return url; 
} 
+0

不错,但不是Character对象,而是一个[Guava'CharMatcher'](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/CharMatcher.html )会更高效 – 2014-06-24 07:25:49

+0

谢谢,但我认为它在内部也使用isLetterOrDigit!如果我不使用Google库,谁又会怎样? – user1079877 2014-06-25 09:29:04

+1

不,它不。它被优化使用位表进行查找。不要使用Google库:也许你应该重新考虑。他们是那里最好的开源库之一 – 2014-06-25 09:57:44

1

你可以在第一次解码时进行解码然后进行编码,如果您有未编码的网址,则不会受解码影响

String url = "your url"; 
    url=URIUtil.decode(url, "UTF-8"); 
    url=URIUtil.encodeQuery(url, "UTF-8"); 
+0

我认为你的意思是[Apache HttpComponents的'URIUtil'](https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/ HTTP /客户端/ utils的/ URIUtils.html) – 2016-10-12 13:16:34