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

发布于 2024-08-04 04:10:07 字数 399 浏览 5 评论 0原文

我在 JSP 页面中有这样一个编码为 big5 的链接 http://hello/world?name=婀ㄉ 当我在浏览器的地址栏中输入它时,它会更改为类似的内容 http://hello/world?name=%23%24%23 当我们想在jsp页面中获取这个参数时,所有的字符都被破坏了。

我们已经这样设置: request.setCharacterEncoding("UTF-8"),这样所有的请求都会转换为UTF8。

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

I have such a link in JSP page with encoding big5
http://hello/world?name=婀ㄉ
And when I input it in browser's URL bar, it will be changed to something like
http://hello/world?name=%23%24%23
And when we want to get this parameter in jsp page, all the characters are corrupted.

And we have set this:
request.setCharacterEncoding("UTF-8"), so all the requests will be converted to UTF8.

But why in this case, it doesn't work ?
Thanks in advance!.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

攒一口袋星星 2024-08-11 04:10:08

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

处理 URI 中的字符编码在 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 在源代码分发中附带了这样的过滤器。

When you enter the URL in browser's address bar, browser may convert the character encoding before URL-encoding. However, this behavior is not well defined, see my question,

Handling Character Encoding in URI on Tomcat

We mostly get UTF-8 and Latin-1 on newer browsers but we get all kinds of encodings (including Big5) in old ones. So it's best to avoid non-ASCII characters in URL entered by user directly.

If the URL is embedded in JSP, you can force it into UTF-8 by generating it like this,

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

On Tomcat, the encoding needs to be specified on Connector like this,

<Connector port="8080" URIEncoding="UTF-8"/>

You also need to use request.setCharacterEncoding("UTF-8") for body encoding but it's not safe to set this in servlet because this only works when the parameter is not processed but other filter or valve may trigger the processing. So you should do it in a filter. Tomcat comes with such a filter in the source distribution.

我要还你自由 2024-08-11 04:10:08

为了避免摆弄 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() 字符串并将其解释为 < code>iso-8859-1 - 或在 server.xml 中设置的 URIEncoding。有关如何从 Tomcat 7 的 server.xml 获取 URIEncoding 字符集的示例,请参阅 此处

To avoid fiddling with the server.xml use :

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));

To actually get those parameters on Tomcat you need to do something like :

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

As apparently (?) request.getParameter URLDecodes() the string and interprets it as iso-8859-1 - or whatever the URIEncoding is set to in the server.xml. For an example of how to get the URIEncoding charset from the server.xml for Tomcat 7 see here

墨小墨 2024-08-11 04:10:08

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

You cannot have non-ASCII characters in an URL - you always need to percent-encode them. When doing so, browsers have difficulties rendering them. Rendering works best if you encode the URL in UTF-8, and then percent-encode it. For your specific URL, this would give http://hello/world?name=%E5%A9%80%E3%84%89 (check your browser what it gives for this specific link). When you get the parameter in JSP, you need to explicitly unquote it, and then decode it from UTF-8, as the browser will send it as-is.

生活了然无味 2024-08-11 04:10:08

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

I had a problem with JBoss 7.0, and I think this filter solution also works with 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);
    }
}
尸血腥色 2024-08-11 04:10:08

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

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

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

I did quite a bit of searching on this issue so this might help others who are experiencing the same problem on tomcat. This is taken from http://wiki.apache.org/tomcat/FAQ/CharacterEncoding.

(How to use UTF-8 everywhere).

  • Set URIEncoding="UTF-8" on your <Connector> in server.xml. References: HTTP Connector, AJP Connector.
  • Use a character encoding filter with the default encoding set to UTF-8
  • Change all your JSPs to include charset name in their contentType.
    For example, use <%@page contentType="text/html; charset=UTF-8" %> for the usual JSP pages and <jsp:directive.page contentType="text/html; charset=UTF-8" /> for the pages in XML syntax (aka JSP Documents).
  • Change all your servlets to set the content type for responses and to include charset name in the content type to be UTF-8.
    Use response.setContentType("text/html; charset=UTF-8") or response.setCharacterEncoding("UTF-8").
  • Change any content-generation libraries you use (Velocity, Freemarker, etc.) to use UTF-8 and to specify UTF-8 in the content type of the responses that they generate.
  • Disable any valves or filters that may read request parameters before your character encoding filter or jsp page has a chance to set the encoding to UTF-8.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文