当前位置: 首页 > 知识库问答 >
问题:

JSP没有为HTML表单帖子显示正确的UTF-8内容

谭献
2023-03-14

我正在使用Java11和Tomcat9以及最新的JSP/JSTL。我正在Windows 10上测试Chrome 71和Firefox 64.0。我有以下测试文件:

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="en-US">
<head>
  <meta charset="UTF-8"/>
  <title>Hello</title>
</head>
<body>
  <c:if test="${not empty param.fullName}">
    <p>Hello, ${param.fullName}.</p>
  </c:if>

  <form>
    <div>
      <label>Full name: <input name="fullName" /></label>
    </div>
    <button>Say Hello</button>
  </form>
</body>
</html>

这可能是最简单的形式。如您所知,表单方法默认为get,表单action默认为"(提交到同一页面),表单enctype默认为Application/x-www-form-urlencoded

如果我在字段中输入名字“Flávio José”(巴西著名歌唱家和音乐家),然后提交,则该表格将通过HTTPGET使用hello提交到同一页面。jsp?全名=Flávio José。这是正确的,页面上写着:

Hello, Flávio José.

如果我将表单方法更改为post,并输入相同的名称“Flávio José”,则表单内容将通过post提交,其中包含HTTP请求内容:

fullName=Fl%C3%A1vio+Jos%C3%A9

这似乎也是正确的。但这一次,页面上说:

Hello, Flávio José.

但它从哪里获得ISO-8859-1?我的JSP页面缺少什么来指示正确的编码?

我还会注意到WHATWG规范说Application/x-www-form-urlencoded八位字节默认应解析为UTF-8。Javaservlet规范是否简单地损坏了?我如何解决这个问题?

共有1个答案

井逸明
2023-03-14

这是Tomcat造成的,但根本问题是Java Servlet 4规范,它不正确且过时。

最初,HTML4.0.1表示,application/x-www-form-urlencoded编码的八位字节应解码为US-ASCII。servlet规范对此进行了更改,表示如果未指定请求编码,则应将八位字节解码为ISO-8859-1。Tomcat只是遵循servlet规范。

JavaServlet规范有两个问题。首先,对application/x-www-form-urlencoded的现代解释是,编码的八位字节应该使用UTF-8进行解码。第二个问题是,将八位字节解码与资源字符集绑定会混淆两个解码级别。

再看一下这个POST内容:

fullName=Fl%C3%A1vio+Jos%C3%A9

您会注意到它是ASCII!!如果您将POSTHTTP请求字符集视为ISO-8859-1UTF-8US-ASCII-您仍然会在解码八位字节之前使用完全相同的Unicode字符!用于解码编码八位字节的编码是完全不同的。

有几个变通方法,其中一些可以通过查看Tomcat字符编码FAQ找到,以“在任何地方使用UTF-8”。

网站中设置请求字符编码。xml文件。

将以下内容添加到WEB-INF/WEB。xml文件:

<request-character-encoding>UTF-8</request-character-encoding>

此设置与servlet容器实现无关,并在servlet规范中定义。(如果您想要一个全局设置,并且不介意更改Tomcat的配置,您也可以将其放入Tomcat的conf/web.xml文件中。)

网站中设置SetCharacterEncodingFilter。xml文件。

Tomcat有一个专有的等价物:在WEB-INF/web.xml文件中使用org.apache.catalina.filters.SetSymEncodingFilter,正如上面Tomcat常见问题解答中提到的,并如https://stackoverflow.com/a/37833977/421049所示,摘录如下:

<filter>
  <filter-name>setCharacterEncodingFilter</filter-name>
  <filter-class>org.apache.catalina.filters.SetCharacterEncodingFilter</filter-class>
  <init-param>
    <param-name>encoding</param-name>
    <param-value>UTF-8</param-value>
  </init-param>
</filter>

<filter-mapping>
  <filter-name>setCharacterEncodingFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

这将使您的web应用程序只在Tomcat上工作,因此最好将其放在Tomcat安装conf/web中。xml文件,正如上面的帖子所提到的。事实上,Tomcat的conf/web。xml安装有这两个部分,但被注释掉了;只需取消对它们的注释,事情就应该正常了。

在JSP或servlet中将请求字符编码强制为UTF-8。

您可以在JSP的早期将servlet请求的字符编码强制为UTF-8:

<% request.setCharacterEncoding("UTF-8"); %>

但这是丑陋的、笨拙的、容易出错的,并且与现代最佳实践背道而驰,不应该再使用JSP Scriptlet了。

希望我们能得到一个更新的Java servlet规范,以消除资源字符集与application/x-www-form-urlencodedoctets解码之间的任何关系,并简单地声明application/x-www-form-urlencodedoctets必须被解码为UTF-8,正如最新的W3C和WHATWG规范所阐明的现代实践。

更新:我已经用这些信息更新了Tomcat关于字符编码问题的常见问题解答。

 类似资料:
  • 我有一个任务: 当我使用命令时: 文本显示不正确。如何修复?谢谢

  • 问题内容: 我使用MySQL 5.1,并从一个270万行的UTF-8解码txt文件加载到一个表中,该表本身声明为,并且所有char字段都声明为,使用… 在数据库本身中,所有字符似乎都是正确的,一切看起来都不错。但是,当我使用php打印它们时,字符显示为???,尽管我在HTML头中使用utf-8声明: 在另一个表(使用utf-8)中,我从提交的表单中插入了文本,这些字符在数据库中奇怪地显示,但是当我

  • 我尝试做一个java web应用程序。在本地Tomcat7服务器上一切都很好。我有一个jsp文件;

  • 问题内容: 我有一个使用ncurses用C编写的程序。它让用户输入并显示它。如果用户输入utf8字符,它将无法正确显示。 我将输入的字符用户保存到文件中。而且我直接在Shell中将此文件正确显示。 我搜索了stackoverflow和google,并尝试了几种方法(例如与ncursesw链接)显示不正确。 我: 可以正确显示用户输入的内容。 如何使ncurses正确显示UTF-8字符? 使用ncu

  • 因此,基本上我使用了下面的代码,它似乎将所有内容完美地放入了查询中,但是,我仍然得到了错误的产品。例如,我请求的产品类别为“冬季”,但仍收到“四季”类别的产品 这是我的密码: print_r返回以下内容: WP_查询对象([Query]=

  • 我使用fiddler监控一个简单的html内容从一个PHP文件运行在localhost。但是每当我按f5刷新页面(浏览器)时,在fiddler中有时整个web会话的字体变成蓝色,即当它实际显示内容(html)时,相反的情况发生在web会话是灰色的时候,它不显示html内容。 注意:始终显示请求/响应标题,这仅用于内容。我还尝试了点技巧(“:80”)并从localhost切换到127.0。0.1.