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

为什么在java中使用request.getParameter()时字符会损坏?,java,character-encoding,request,Java,Character Encoding,Request,我在JSP页面中有这样一个链接,编码为big5 当我在浏览器的URL栏中输入它时,它会变成 当我们想在jsp页面中获取此参数时,所有字符都已损坏 我们已经确定了这一点: setCharacterEncoding(“UTF-8”),因此所有请求都将转换为UTF8 但为什么在这种情况下,它不起作用? 提前谢谢 URL中不能包含非ASCII字符-始终需要对其进行百分比编码。执行此操作时,浏览器很难呈现它们。如果使用UTF-8编码URL,然后对其进行百分比编码,则渲染效果最佳。对于您的特定URL,这将提

我在JSP页面中有这样一个链接,编码为big5 当我在浏览器的URL栏中输入它时,它会变成 当我们想在jsp页面中获取此参数时,所有字符都已损坏

我们已经确定了这一点: setCharacterEncoding(“UTF-8”),因此所有请求都将转换为UTF8

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

URL中不能包含非ASCII字符-始终需要对其进行百分比编码。执行此操作时,浏览器很难呈现它们。如果使用UTF-8编码URL,然后对其进行百分比编码,则渲染效果最佳。对于您的特定URL,这将提供(检查您的浏览器,它为该特定链接提供了什么)。当您在JSP中获取参数时,需要显式地将其解压缩,然后从UTF-8对其进行解码,因为浏览器将按原样发送。

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

在较新的浏览器上,我们大多使用UTF-8和拉丁语-1,但在旧的浏览器中,我们使用各种编码(包括Big5)。所以最好避免用户直接输入URL中的非ASCII字符

如果URL嵌入到JSP中,您可以通过如下方式将其强制生成到UTF-8中

String link = "http://hello/world?name=" + URLEncoder.encode(name, "UTF-8");
<Connector port="8080" URIEncoding="UTF-8"/>
在Tomcat上,需要在连接器上指定编码,如下所示

String link = "http://hello/world?name=" + URLEncoder.encode(name, "UTF-8");
<Connector port="8080" URIEncoding="UTF-8"/>


您还需要使用
request.setCharacterEncoding(“UTF-8”)
进行正文编码,但在servlet中设置此项并不安全,因为这仅在未处理参数时有效,但其他过滤器或阀可能会触发处理。所以你应该在过滤器里做。Tomcat在源代码发行版中附带了这样一个过滤器。

为了避免篡改
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上实际获取这些参数:


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

我在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);
    }
}

我在这个问题上做了很多搜索,所以这可能会帮助在tomcat上遇到相同问题的其他人。这是从一本书中摘取的

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

  • 在server.xml中的
    上设置URIEncoding=“UTF-8”。参考:HTTP连接器,AJP连接器
  • 使用默认编码设置为UTF-8的字符编码筛选器
  • 更改所有JSP以在其contentType中包含字符集名称。 例如,用于通常的JSP页面,
    用于XML语法的页面(也称为JSP文档)
  • 将所有servlet更改为将响应的内容类型设置为UTF-8,并将内容类型中的字符集名称包括为UTF-8。 使用response.setContentType(“text/html;charset=UTF-8”)或response.setCharacterEncoding(“UTF-8”)
  • 将您使用的任何内容生成库(Velocity、Freemarker等)更改为使用UTF-8,并在它们生成的响应的内容类型中指定UTF-8
  • 在您的字符编码过滤器或jsp页面有机会将编码设置为UTF-8之前,禁用可能读取请求参数的任何阀或过滤器
但如何对其进行编码?将其从非ASCII更改为百分比编码?我应该在java中使用什么函数?如何更改
getParameter
的默认编码?@emab:来自
server.xml
,如其他答案中所述。如果您也有类似问题,请提出一个新问题。这不是问题。我用这个过滤器解决了同样的问题。