Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/385.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么';ServletContext#setRequestCharacterEncoding';不影响';HttpServletRequest#getReader';?_Java_Servlet 4 - Fatal编程技术网

Java 为什么';ServletContext#setRequestCharacterEncoding';不影响';HttpServletRequest#getReader';?

Java 为什么';ServletContext#setRequestCharacterEncoding';不影响';HttpServletRequest#getReader';?,java,servlet-4,Java,Servlet 4,我们可以通过ServletContext#setRequestCharacterEncoding(自Servlet4.0以来)设置默认字符编码以用于读取请求正文 我认为HttpServletRequest#getReader的字符编码可以使用ServletContext#setRequestCharacterEncoding(*)设置 但是HttpServletRequest#getReader返回的读取器似乎没有使用ServletContext#setRequestCharacterEncod

我们可以通过
ServletContext#setRequestCharacterEncoding
(自Servlet4.0以来)设置默认字符编码以用于读取请求正文

我认为
HttpServletRequest#getReader
的字符编码可以使用
ServletContext#setRequestCharacterEncoding(*)
设置

但是
HttpServletRequest#getReader
返回的读取器似乎没有使用
ServletContext#setRequestCharacterEncoding
设置的编码来解码字符

我的问题是:

  • 为什么
    ServletContext#setRequestCharacterEncoding
    HttpServletRequest#getReader
    没有影响(但对
    HttpServletRequest#getParameter
    有影响)
  • 是否有任何规范描述此类
    ServletContext#setRequestCharacterEncoding
    HttpServletRequest#getReader
    行为
(我阅读了Servlet规范4.0版,但找不到任何关于此类行为的规范。)

我创建了一个简单的war应用程序,并测试了
ServletContext\setRequestCharacterEncoding

[环境]

  • Tomcat9.0.19(我不更改任何默认配置)
  • JDK11
  • Windows8.1
[index.html]

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
</head>
<body>
    <form action="/SimpleWarApp/app/simple" method="post">
        <!-- The value is Japanese character '\u3042' -->
        <input type="text" name="hello" value="あ"/>
        <input type="submit" value="submit!"/>
    </form>
    <button type="button" id="the_button">post</button>
    <script>
        document.getElementById('the_button').addEventListener('click', function() {
            var xhttp = new XMLHttpRequest();
            xhttp.open('POST', '/SimpleWarApp/app/simple');
            xhttp.setRequestHeader('Content-Type', 'text/plain');
            <!-- The body content is Japanese character '\u3042' -->
            xhttp.send('あ');
        });
    </script>
</body>
</html>
[SimpleServlet.java]

@WebServlet("/app/simple")
@SuppressWarnings("serial")
public class SimpleServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // req.setCharacterEncoding("UTF-8");
        System.out.println("requestCharacterEncoding : " + req.getServletContext().getRequestCharacterEncoding());
        System.out.println("req.getCharacterEncoding() : " + req.getCharacterEncoding());

        String hello = req.getParameter("hello");
        if (hello != null) {
            System.out.println("hello : " + req.getParameter("hello"));
        } else {
            System.out.println("body : " + req.getReader().readLine());
        }
    }
}
我没有任何servlet过滤器。 以上三个都是此war应用程序的组件。 ()

案例1: 当我提交带有参数“hello”的表单时,“hello”的值被成功解码如下

requestCharacterEncoding : UTF-8
req.getCharacterEncoding() : UTF-8
hello : あ
案例2: 当我单击“发布”并发送文本内容时,请求正文无法成功解码,如下所示。 (尽管我确认请求主体由UTF-8编码,如下所示:
E3 81 82

案例3: 当我在servlet的“doPost”方法的第一行使用
HttpServletRequest#setCharacterEncoding
设置编码时,请求正文成功解码

requestCharacterEncoding : UTF-8
req.getCharacterEncoding() : UTF-8
body : あ
requestCharacterEncoding : UTF-8
req.getCharacterEncoding() : UTF-8
body : あ
requestCharacterEncoding : UTF-8
req.getCharacterEncoding() : UTF-8
body : ???
案例4: 当我使用http.setRequestHeader('Content-Type','text/plain;charset=UTF-8')javascript,请求正文已成功解码

requestCharacterEncoding : UTF-8
req.getCharacterEncoding() : UTF-8
body : あ
requestCharacterEncoding : UTF-8
req.getCharacterEncoding() : UTF-8
body : あ
requestCharacterEncoding : UTF-8
req.getCharacterEncoding() : UTF-8
body : ???
案例5: 当我不调用
req.getParameter(“hello”)
时,无法成功解码请求正文

requestCharacterEncoding : UTF-8
req.getCharacterEncoding() : UTF-8
body : あ
requestCharacterEncoding : UTF-8
req.getCharacterEncoding() : UTF-8
body : あ
requestCharacterEncoding : UTF-8
req.getCharacterEncoding() : UTF-8
body : ???
案例6: 当我不在
InitServletContextListener.java
调用
ServletContext#setRequestCharacterEncoding
时,不会设置字符编码

requestCharacterEncoding : null
req.getCharacterEncoding() : null
body : ???
[注]

  • (*)我这样认为是因为:

    • (1) HttpServletRequest#getReader的java文档说 “读取器根据正文上使用的字符编码翻译字符数据”

    • (2) HttpServletRequest的java文档#getCharacterEncoding说 “返回此请求正文中使用的字符编码的名称”

    • (3) HttpServletRequest的java文档#getCharacterEncoding也说 “以下指定请求字符编码的方法按优先级降序查阅:每个请求,每个web应用(使用ServletContext.setRequestCharacterEncoding,部署描述符)”

  • ServletContext#setResponseCharacterEncoding
    工作正常。当我使用
    ServletContext#setResponseCharacterEncoding
    时,
    HttpServletResponse#getWriter
    返回的编写器通过它设置的字符编码对响应体进行编码


这是一个Apache Tomcat bug(特定于
getReader()
),由于您在Tomcat用户邮件列表上的报告,它将在9.0.21以后得到修复


好奇的是,如果您使用http.setRequestHeader('Content-Type','text/plain;charset=UTF-8');`javascript?你的发现很有趣。另外,如果在读取主体缓冲区之前不调用`req.getParameter(“hello”)`会发生什么情况?在servlet顶部是否有任何requestfilters来破坏request.characterencoding属性?如果不设置context.characterencoding,则有差异。我认为应该从请求中获取NULL。如果没有设置值,则getCharacterEncoding()将其设置为空。我已经测试了“http.setRequestHeader('Content-Type','text/plain;charset=UTF-8');`javascript(案例4)和servlet不调用
req.getParameter(“hello”)
(案例5)。我已经编辑了我的问题。我没有任何Servlet过滤器。以上三个都是我的war应用程序的组件。我已经测试了应用程序没有调用
ServletContext#setRequestCharacterEncoding
(案例6)。我已经编辑了我的问题。可能是Tomcat bug。我认为最好不要使用
context.setRequestCharacterEncoding
方法。检查请求。getCharacterEncoding()==null然后在每个servlet代码上设置UTF-8编码。