我问了同样的问题,
在Tomcat上处理URI中的字符编码
我最近找到了一个解决方案,对我来说效果很好。您可能需要尝试一下。这是您需要做的,
- 将您的URI编码保留为Latin-1。在Tomcat上,将URIEncoding =“ ISO-8859-1”添加到server.xml中的连接器。
- 如果必须手动进行URL解码,也可以将Latin1用作字符集。
- 使用fixEncoding()函数修正编码。
例如,要从查询字符串获取参数,
String name = fixEncoding(request.getParameter("name"));您可以始终这样做。正确编码的字符串不会更改。
该代码已附加。祝好运!
public static String fixEncoding(String latin1) { try { byte[] bytes = latin1.getBytes("ISO-8859-1"); if (!validUTF8(bytes)) return latin1; return new String(bytes, "UTF-8"); } catch (UnsupportedEncodingException e) { // Impossible, throw unchecked throw new IllegalStateException("No Latin1 or UTF-8: " + e.getMessage()); } } public static boolean validUTF8(byte[] input) { int i = 0; // Check for BOM if (input.length >= 3 && (input[0] & 0xFF) == 0xEF && (input[1] & 0xFF) == 0xBB & (input[2] & 0xFF) == 0xBF) { i = 3; } int end; for (int j = input.length; i < j; ++i) { int octet = input[i]; if ((octet & 0x80) == 0) { continue; // ASCII } // Check for UTF-8 leading byte if ((octet & 0xE0) == 0xC0) { end = i + 1; } else if ((octet & 0xF0) == 0xE0) { end = i + 2; } else if ((octet & 0xF8) == 0xF0) { end = i + 3; } else { // Java only supports BMP so 3 is max return false; } while (i < end) { i++; octet = input[i]; if ((octet & 0xC0) != 0x80) { // Not a valid trailing byte return false; } } } return true; }编辑:您的方法由于各种原因而行不通。当出现编码错误时,您不能指望从Tomcat获得的内容。有时你会得到``?’‘?有时候,您什么也得不到,getParameter()返回null。假设您可以检查“?”,那么查询字符串包含有效的“?”会发生什么情况??
此外,您不应拒绝任何请求。这不是您用户的错。正如我在原始问题中提到的那样,浏览器可以使用UTF-8或Latin-1编码URL。用户无法控制。您需要接受两者。将您的servlet更改为Latin-1会保留所有字符,即使它们是错误的也是如此,从而使我们有机会对其进行修复或丢弃。
我在这里发布的解决方案并不完美,但这是迄今为止我们发现的最好的解决方案。



