HttpServletRequest - setCharacterEncoding似乎什么都不做

时间:2010-07-19 06:34:16

标签: java character-encoding servlets

我正在尝试从请求中读取UTF-8信息。 我使用了“request.setCharacterEncoding(”UTF-8“);”,但它似乎什么都不做 - 信息读取是非UTF-8。

我做错了什么?

8 个答案:

答案 0 :(得分:24)

如果您使用的是tomcat,还应在连接器中将URIEncoding设置为UTF-8:

<Server port="8105" shutdown="SHUTDOWN">
...
    <Service name="Catalina">
        <Connector port="8180" URIEncoding="UTF-8" />
        <Engine name="Catalina" defaultHost="localhost">
            <Host name="localhost" appBase="webapps" />
        </Engine>
    </Service>
</Server>

答案 1 :(得分:19)

HttpServletRequest#setCharacterEncoding()仅在请求为POST请求请求正文尚未处理时生效。

因此,如果它在您的情况下不起作用,那么它可能有两个原因:

  1. 您实际上是在发送GET个请求。即请求参数在请求URL而不是请求主体中从客户端发送到服务器。请求URL由Web服务器处理,而不是由Servlet API处理。因此,要解决此问题,您需要配置相关的Web服务器,以使用指定的字符编码对请求URL(URI)进行解码。例如,在Apache Tomcat的情况下,您需要将URIEncodingserver.xml元素的UTF-8属性设置为POST

  2. 您正确使用getParameterXXX(),但您已经(间接)处理了请求正文,因此更改字符编码为时已晚。只有在Filter方法上进行第一次调用时,才会完全处理请求正文。其中有<Connector>个。它不会在后续调用中重新处理。当确定谁在调用此方法时,请不要忘记考虑web.xml中所有已声明的{{1}}个实例。其中一些人可能会抓住并扫描参数。

  3. 如果仍然没有任何帮助,那么剩下的唯一可能原因是显示控制台或记录器或用于打印/确定/调试获得的请求参数的任何内容都不支持UTF-8。您想重新配置控制台/记录器/ etc以使用UTF-8来显示字符。如果它是例如Eclipse控制台,则可以通过 Window&gt;设置它。偏好&gt;一般&gt;工作区&gt;文本文件编码

    另见:

    • several更多背景信息,实际示例和解决方案。

答案 2 :(得分:5)

这种方法真的很愚蠢。它不应该存在,你不应该使用它。

对于POST请求中的正文,编码应该由Content-Type标头中的客户端显式定义。如果没有,这是一个糟糕的要求。 [1]

对于GET请求URI,客户端不能指定编码,并且服务器必须具有隐式编码,并且程序员需要设置编码,但Servlet API中不存在该方法!

但是,你的servlet容器可能有一种专有的方法。

最好的方法可能是将JVM的默认编码设置为UTF-8。

1:http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7.1

“charset”参数与某些媒体类型一起用于定义数据的字符集(第3.4节)。当发件人未提供显式字符集参数时,“text”类型的媒体子类型被定义为在通过HTTP接收时具有默认字符集值“ISO-8859-1”。除“ISO-8859-1”或其子集必须以外的字符集中的数据都标有适当的字符集值。

答案 3 :(得分:2)

问题取决于使用的应用程序服务器。我在link中找到的最佳描述。

在某些应用程序服务器中,request.setCharacterEncoding(...)在使用描述符设置应用程序编码之前无效。最复杂的是JBoss,Apache Tomcat,Glassfish。更好的是WebLogic,最好的是Jetty(UTF-8是默认设置)。

在我的情况下,我必须创建一个glassfish-web.xml描述符并将parameter-encoding标记放在那里。就我而言,对于GlassFish:

<glassfish-web-app error-url="">
    <!-- request.setCharacterEncoding("UTF-8") not functioning without this setting-->
    <parameter-encoding default-charset="UTF-8" />
</glassfish-web-app>

答案 4 :(得分:1)

你是否在任何request.getParameter调用之后这样做。

必须在任何request.setCharacterEncoding("UTF-8")来电之前调用{p> request.getParameter()

答案 5 :(得分:1)

只是为了确认对于POST参数,你必须在获取参数之前调用request.setCharacterEncoding(...)。 对于GET参数,它取决于您正在使用的Web容器(使用Maurice Perry对Tomcat的回答)。

请查看此链接以获取更多信息。 “从浏览器到数据库的字符转换” http://java.sun.com/developer/technicalArticles/Intl/HTTPCharset/

答案 6 :(得分:0)

(至于第一个问题..)
如果您从正文中读取参数,也可以使用自己的编码读取每个项目(查看最后一行):

ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
List items = null;
try {
    items = upload.parseRequest(request);
} catch (FileUploadException ex) {
    logger.warn("Fail during file upload");
    return uploads;
}

Iterator itr = items.iterator();
while (itr.hasNext()) {
    FileItem item = (FileItem) itr.next();
    if (item.isFormField()) {
        String name = item.getFieldName();
        System.out.println("name: " + name);
        String value = item.getString();
        System.out.println("get as utf8 - "+item.getString("UTF-8"));

答案 7 :(得分:0)

对于jboss / wildfly,有一个功能请求https://issues.jboss.org/browse/WFLY-2533

将其放入WEB-INF / jboss-web.xml:

import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;

public class Test {
    public static void main(String... args) {
        final Integer[] ignore = new Integer[]{310, 321, 332, 343, 354, 365, 376, 387};
        final List<Integer> ignoreList = Arrays.asList(ignore);
        try (
                final IntStream stream = IntStream.rangeClosed(305, 397)) {
            stream.filter(x -> !ignoreList.contains(x)).forEach(System.out::println);
        }
    }
}