Java HTML:表单不发送UTF-8格式的输入
我已经访问了关于HTML中UTF-8编码的每一个问题,但似乎没有什么能让它像预期的那样工作 我添加了Java HTML:表单不发送UTF-8格式的输入,java,html,forms,jsp,utf-8,Java,Html,Forms,Jsp,Utf 8,我已经访问了关于HTML中UTF-8编码的每一个问题,但似乎没有什么能让它像预期的那样工作 我添加了meta标记:没有任何更改。 我在表单中添加了接受字符集属性:没有任何更改。 JSP文件 您可以在字符集中使用与ISO相关的字符串,在JSP代码中使用页面编码定义 类似于charset=“ISO-8859-1”和pageEncoding=“ISO-8859-1”。根据您发布的输出,参数似乎以UTF8的形式发送,随后字符串的unicode字节被解释为ISO-8859-1 下面的代码片段演示了您观察
meta
标记:没有任何更改。我在
表单
中添加了接受字符集
属性:没有任何更改。JSP文件
您可以在字符集中使用与ISO相关的字符串,在JSP代码中使用页面编码定义
类似于charset=“ISO-8859-1”和pageEncoding=“ISO-8859-1”。根据您发布的输出,参数似乎以UTF8的形式发送,随后字符串的unicode字节被解释为ISO-8859-1 下面的代码片段演示了您观察到的行为
String eGrave = "\u00E8"; // the letter è
System.out.printf("letter UTF8 : %s%n", eGrave);
byte[] bytes = eGrave.getBytes(StandardCharsets.UTF_8);
System.out.printf("UTF-8 hex : %X %X%n",
bytes[0], bytes[1], bytes[0], bytes[1]
);
System.out.printf("letter ISO-8859-1: %s%n",
new String(bytes, StandardCharsets.ISO_8859_1)
);
输出
letter UTF8 : è
UTF-8 hex : C3 A8
letter ISO-8859-1: è
对我来说,表单发送正确的UTF8编码数据,但稍后该数据不会被视为UTF8
编辑要尝试的其他要点:输出您请求的字符编码
System.out.println(request.getCharacterEncoding())
强制使用UTF-8检索参数(未经测试,仅为一个想法)
我添加了meta
标记:没有任何更改
当页面通过HTTP而不是通过本地磁盘文件系统(即页面的URL为http://...
而不是例如file://...
)。在HTTP中,将使用HTTP响应头中的字符集。您已将其设置为如下所示:
<%@page pageEncoding="UTF-8"%>
如上所述,这将告诉JSP引擎使用UTF-8编写HTTP响应输出,并将其设置在HTTP响应头中。在发送回服务器之前,webbrowser将使用相同的字符集对HTTP请求参数进行编码
您唯一缺少的步骤是告诉服务器在返回getParameterXxx()
调用之前必须使用UTF-8解码HTTP请求参数。如何全局实现这一点取决于HTTP请求方法。考虑到您使用的是POST方法,使用下面的servlet筛选器类可以相对容易地实现这一点,该类可以自动钩住所有请求:
@WebFilter("/*")
public class CharacterEncodingFilter implements Filter {
@Override
public void init(FilterConfig config) throws ServletException {
// NOOP.
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
}
@Override
public void destroy() {
// NOOP.
}
}
就这些。在Servlet3.0+(Tomcat7和更新版本)中,您不需要额外的web.xml
配置
您只需要记住,在第一次使用任何getParameterXxx()
方法获取POST请求参数之前调用setCharacterEncoding()
方法非常重要。这是因为它们在第一次访问时只解析一次,然后缓存在服务器内存中
例如,下面的顺序是错误的:
String foo = request.getParameter("foo"); // Wrong encoding.
// ...
request.setCharacterEncoding("UTF-8"); // Attempt to set it.
String bar = request.getParameter("bar"); // STILL wrong encoding!
在servlet过滤器中执行setCharacterEncoding()
作业将确保它及时运行(至少在任何servlet之前)
如果您希望指示服务器也使用UTF-8解码GET(而不是POST)请求参数(您知道,URL中
?
字符后看到的参数),那么您基本上需要在服务器端对其进行配置。不可能通过ServletAPI对其进行配置。例如,如果您使用Tomcat作为服务器,那么需要在Tomcat自己的/conf/server.xml
元素的
中添加URIEncoding=“UTF-8”
属性
如果您仍然在System.out.println()调用的控制台输出中看到,那么stdout本身没有配置为使用UTF-8的可能性很大。如何做到这一点取决于谁负责解释和呈现标准。例如,如果您使用Eclipse作为IDE,则需要将窗口>首选项>常规>工作区>文本文件编码设置为UTF-8
另见:
预热
让我先说一个普遍的事实,我们都知道计算机除了0和1之外什么都不懂
现在,当您通过HTTP提交HTML表单,并且值通过网络传输到目标服务器时,实际上会传递大量位-0和1
- 在将数据发送到服务器之前,HTTP客户端(浏览器或curl等)将使用某种编码方案对其进行编码,并期望服务器使用相同的方案对其进行解码,以便服务器准确地知道客户端发送了什么
- 在将响应发送回客户机之前,服务器将使用某种编码方案对其进行编码,并期望客户机使用相同的方案对其进行解码,以便客户机确切地知道服务器发送了什么
一个类似的例子是,我给你发了一封信,告诉你信是用英语、法语还是荷兰语写的,这样你就能得到我想要给你的确切信息。在回答我的时候,你也会提到我应该读哪种语言
重要的一点是,当数据离开客户端时,它将被编码,并在服务器端解码,反之亦然。如果您没有指定任何内容,那么在从客户端转到服务器端之前,内容将按照进行编码
核心概念
阅读热身很重要。你需要做几件事来确保达到预期的结果
- 在将数据从客户端发送到服务器之前设置正确的编码
- 在服务器端设置了正确的解码和编码,以读取请求并将响应写回客户端(这就是您无法获得预期结果的原因)
- 确保所有使用相同编码方案的地方都不会出现这样的情况:在客户端,您使用ISO-8859-1编码,在服务器上,您使用UTF-8解码,否则会出现错误(根据我的类比,我用英语给您写信,您用法语阅读)
- 如果尝试使用Windows命令行或Eclipse日志查看器等使用日志进行验证,请为日志查看器设置正确的编码。(这是导致问题的原因,但不是主要原因,因为从请求对象读取的数据首先没有正确解码。Windows
request.setCharacterEncoding("UTF-8");
... request.getParameter(...);
<%@page pageEncoding="UTF-8"%>
@WebFilter("/*")
public class CharacterEncodingFilter implements Filter {
@Override
public void init(FilterConfig config) throws ServletException {
// NOOP.
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
}
@Override
public void destroy() {
// NOOP.
}
}
String foo = request.getParameter("foo"); // Wrong encoding.
// ...
request.setCharacterEncoding("UTF-8"); // Attempt to set it.
String bar = request.getParameter("bar"); // STILL wrong encoding!
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>
com.sks.hagrawal.EncodingFilter
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
public class EncodingFilter implements Filter {
private String encoding = "UTF-8";
private boolean forceEncoding = false;
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
request.setCharacterEncoding(encoding);
if(forceEncoding){ //If force encoding is set then it means that set response stream encoding as well ...
response.setCharacterEncoding(encoding);
}
filterChain.doFilter(request, response);
}
public void init(FilterConfig filterConfig) throws ServletException {
String encodingParam = filterConfig.getInitParameter("encoding");
String forceEncoding = filterConfig.getInitParameter("forceEncoding");
if (encodingParam != null) {
encoding = encodingParam;
}
if (forceEncoding != null) {
this.forceEncoding = Boolean.valueOf(forceEncoding);
}
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
System.out.println("CharacterEncoding = " + request.getCharacterEncoding());
request.setCharacterEncoding("UTF-8");
System.out.println("CharacterEncoding = " + request.getCharacterEncoding());
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="UTF-8"%>
resp.setContentType("text/html;charset=UT-8");