在java中使用request.getParameter()时为什么字符被破坏?

我在JSP页面中有这样一个链接,编码为big5 http:// hello / world?name =婀ㄉ当我在浏览器的URL栏中输入它时,它将被改为http:// hello / world?name = %23%24%23当我们想在jsp页面中获取此参数时,所有字符都已损坏。

我们设置了这个:request.setCharacterEncoding(“UTF-8”),因此所有请求都将转换为UTF8。

但为什么在这种情况下,它不起作用? 提前致谢!。

当您在浏览器的地址栏中输入URL时,浏览器可能会在URL编码之前转换字符编码。 但是,这种行为定义不明确,请参阅我的问题,

在Tomcat上处理URI中的字符编码

我们主要在较新的浏览器上获得UTF-8和Latin-1,但我们在旧版本中获得各种编码(包括Big5)。 因此,最好避免用户直接输入的URL中的非ASCII字符。

如果URL嵌入在JSP中,您可以通过生成它来强制它为UTF-8,

String link = "http://hello/world?name=" + URLEncoder.encode(name, "UTF-8"); 

在Tomcat上,需要像这样在Connector上指定编码,

  

您还需要使用request.setCharacterEncoding("UTF-8")进行主体编码,但在servlet中设置它是不安全的,因为这仅在未处理参数但其他filter或阀门可能触发处理时才有效。 所以你应该在filter中做到这一点。 Tomcat在源代码发行版中附带了这样的filter。

为避免摆弄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上实际获取这些参数, 您需要执行以下操作 :

 final String name = new String(request.getParameter("name").getBytes("iso-8859-1"), "UTF-8"); 

显然(?) request.getParameter URLDecodes()字符串并将其解释为iso-8859-1 – 或者在server.xml设置为URIEncoding任何内容。 有关如何从Tomcat 7的server.xml获取URIEncoding字符集的示例,请参见此处

您不能在URL中包含非ASCII字符 – 您始终需要对它们进行百分比编码。 这样做时,浏览器难以渲染它们。 如果您使用UTF-8对URL进行编码,然后对其进行百分比编码,则渲染效果最佳。 对于您的特定URL,这将给出http://hello/world?name=%E5%A9%80%E3%84%89 (检查您的浏览器为此特定链接提供的内容)。 当您在JSP中获取参数时,您需要显式取消引用它,然后从UTF-8解码它,因为浏览器将按原样发送它。

我遇到了JBoss 7.0的问题,我认为这个filter解决方案也适用于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); } } 

我在这个问题上做了很多搜索,所以这可能会帮助那些在tomcat上遇到同样问题的人。 这取自http://wiki.apache.org/tomcat/FAQ/CharacterEncoding 。

(如何在任何地方使用UTF-8)。

  • 在server.xml中的上设置URIEncoding =“UTF-8”。 参考:HTTP连接器,AJP连接器。
  • 使用字符编码筛选器,默认编码设置为UTF-8
  • 更改所有JSP以在其contentType中包含charset名称。 例如,对于通常的JSP页面使用<%@ page contentType =“text / html; charset = UTF-8”%>,并使用用于XML语法的页面(又名JSP文档)。
  • 更改所有servlet以设置响应的内容类型,并将内容类型中的charset名称包含为UTF-8。 使用response.setContentType(“text / html; charset = UTF-8”)或response.setCharacterEncoding(“UTF-8”)。
  • 更改您使用的任何内容生成库(Velocity,Freemarker等)以使用UTF-8并在其生成的响应的内容类型中指定UTF-8。
  • 在字符编码filter或jsp页面有机会将编码设置为UTF-8之前,禁用可能读取请求参数的任何阀门或filter。