我在JSP页面中有这样的链接,编码为big5 http://hello/world?name=婀ㄉ 当我在浏览器的URL栏中输入它时,它将被改为类似的东西 http://hello/world?name=%23%24%23 当我们想在jsp页面中获取此参数时,所有字符都已损坏。
我们设置了这个: request.setCharacterEncoding(“UTF-8”),因此所有请求都将转换为UTF8。
但是为什么在这种情况下,它不起作用? 提前谢谢!。
答案 0 :(得分:14)
当您在浏览器的地址栏中输入URL时,浏览器可能会在URL编码之前转换字符编码。但是,这种行为定义不明确,请参阅我的问题,
Handling Character Encoding in URI on Tomcat
我们主要在较新的浏览器上获得UTF-8和Latin-1,但我们在旧版本中获得各种编码(包括Big5)。因此,最好避免用户直接输入的URL中的非ASCII字符。
如果URL嵌入在JSP中,您可以通过生成它来强制它为UTF-8,
String link = "http://hello/world?name=" + URLEncoder.encode(name, "UTF-8");
在Tomcat上,需要在Connector上指定编码,
<Connector port="8080" URIEncoding="UTF-8"/>
您还需要使用request.setCharacterEncoding("UTF-8")
进行正文编码,但在servlet中设置它是不安全的,因为这仅在未处理参数但其他过滤器或阀门可能触发处理时才有效。所以你应该在过滤器中做到这一点。 Tomcat在源代码发布中附带了这样的过滤器。
答案 1 :(得分:8)
为避免摆弄server.xml
使用:
protected static final String CHARSET_FOR_URL_ENCODING = "UTF-8";
protected String encodeString(String baseLink, String parameter)
throws UnsupportedEncodingException {
return String.format(baseLink + "%s",
URLEncoder.encode(parameter, CHARSET_FOR_URL_ENCODING));
}
// Used in the servlet code to generate GET requests
response.sendRedirect(encodeString("userlist?name=", name));
要在Tomcat you need to do something like上实际获取这些参数:
final String name =
new String(request.getParameter("name").getBytes("iso-8859-1"), "UTF-8");
显然(?)request.getParameter
URLDecodes()字符串并将其解释为iso-8859-1
- 或URIEncoding
中server.xml
设置的任何内容。有关如何从Tomcat 7的URIEncoding
获取server.xml
字符集的示例,请参阅here
答案 2 :(得分:6)
您不能在网址中包含非ASCII字符 - 您始终需要对它们进行百分比编码。这样做时,浏览器难以渲染它们。如果您以UTF-8编码URL,然后对其进行百分比编码,则渲染效果最佳。对于您的特定网址,这会给http://hello/world?name=%E5%A9%80%E3%84%89
(请检查您的浏览器为此特定链接提供的内容)。当您在JSP中获取参数时,您需要显式取消引用它,然后从UTF-8解码它,因为浏览器将按原样发送它。
答案 3 :(得分:0)
我遇到了JBoss 7.0的问题,我认为这个过滤器解决方案也适用于Tomcat:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
try {
httpRequest.setCharacterEncoding(MyAppConfig.getAppSetting("System.Character.Encoding"));
String appServer = MyAppConfig.getAppSetting("System.AppServer");
if(appServer.equalsIgnoreCase("JBOSS7")) {
Field requestField = httpRequest.getClass().getDeclaredField("request");
requestField.setAccessible(true);
Object requestValue = requestField.get(httpRequest);
Field coyoteRequestField = requestValue.getClass().getDeclaredField("coyoteRequest");
coyoteRequestField.setAccessible(true);
Object coyoteRequestValue = coyoteRequestField.get(requestValue);
Method getParameters = coyoteRequestValue.getClass().getMethod("getParameters");
Object parameters = getParameters.invoke(coyoteRequestValue);
Method setQueryStringEncoding = parameters.getClass().getMethod("setQueryStringEncoding", String.class);
setQueryStringEncoding.invoke(parameters, MyAppConfig.getAppSetting("System.Character.Encoding"));
Method setEncoding = parameters.getClass().getMethod("setEncoding", String.class);
setEncoding.invoke(parameters, MyAppConfig.getAppSetting("System.Character.Encoding"));
}
} catch (NoSuchMethodException nsme) {
System.err.println(nsme.getLocalizedMessage());
nsme.printStackTrace();
MyLogger.logException(nsme);
} catch (InvocationTargetException ite) {
System.err.println(ite.getLocalizedMessage());
ite.printStackTrace();
MyLogger.logException(ite);
} catch (IllegalAccessException iae) {
System.err.println(iae.getLocalizedMessage());
iae.printStackTrace();
MyLogger.logException(iae);
} catch(Exception e) {
TALogger.logException(e);
}
try {
httpResponse.setCharacterEncoding(MyAppConfig.getAppSetting("System.Character.Encoding"));
} catch(Exception e) {
MyLogger.logException(e);
}
}
答案 4 :(得分:0)
我在这个问题上做了很多搜索,所以这可能会帮助那些在tomcat上遇到同样问题的人。这取自http://wiki.apache.org/tomcat/FAQ/CharacterEncoding。
(如何在任何地方使用UTF-8)。
<Connector>
上。参考:HTTP连接器,AJP连接器。<jsp:directive.page contentType="text/html; charset=UTF-8" />
用于XML语法中的页面(也称为JSP文档)。