我正在使用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规范是否简单地损坏了?我如何解决这个问题?
这是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!!如果您将POST
HTTP请求字符集视为ISO-8859-1
、UTF-8
或US-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-urlencoded
octets解码之间的任何关系,并简单地声明application/x-www-form-urlencoded
octets必须被解码为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.