繁体   English   中英

当表单作为 multipart/form-data 发布时,UTF-8 文本出现乱码

[英]UTF-8 text is garbled when form is posted as multipart/form-data

我正在将文件上传到服务器。 文件上传 HTML 表单有 2 个字段:

  1. 文件名 - 一个 HTML 文本框,用户可以在其中指定任何语言的名称。
  2. 文件上传 - 一个 HTMl“文件”,用户可以在其中指定要从磁盘上传的文件。

当表单提交时,文件内容被正确接收。 但是,读取文件名(上面的第1点)时,却是乱码。 正确显示 ASCII 字符。 当名称以其他语言(德语、法语等)命名时,就会出现问题。

在servlet 方法中,请求的字符编码设置为UTF-8。 我什至尝试做一个如上所述的过滤器 - 如何使此代码使用 jQuery/Ajax 提交 UTF-8 表单 textarea 工作? - 但它似乎不起作用。 只有文件名似乎是乱码。

文件名所在的 MySQL 表支持 UTF-8。 我给出了随机的非英文字符,它们被正确存储/显示。

使用 Fiddler,我监视了请求并且所有 POST 数据都正确传递。 我正在尝试确定数据如何/哪里会出现乱码。 任何帮助将不胜感激。

我在使用 Apache commons-fileupload 时遇到了同样的问题。 我没有找出导致问题的原因,特别是因为我在以下位置使用 UTF-8 编码:1. HTML 元标记 2. 表单接受字符集属性 3. Tomcat 过滤器对每个设置“UTF-8”的请求编码

-> 我的解决方案是特别将字符串从 ISO-8859-1(或任何平台的默认编码)转换为 UTF-8:

new String (s.getBytes ("iso-8859-1"), "UTF-8");

希望有帮助

编辑:从 Java 7 开始,您还可以使用以下内容:

new String (s.getBytes (StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);

只需使用 Apache 公共上传库。 URIEncoding="UTF-8"添加到 Tomcat 的连接器,并使用 FileItem.getString("UTF-8") 而不是 FileItem.getString() 没有指定字符集。

希望这有帮助。

我被这个问题困住了,发现这是调用的顺序

request.setCharacterEncoding("UTF-8");

那是造成问题的原因。 它必须在对 request.getParameter() 的所有调用之前调用,因此我制作了一个特殊的过滤器以在过滤器链的顶部使用。

https://rogerkeays.com/servletrequest-setcharactercoding-ignored

我有同样的问题,结果证明除了在过滤器中指定编码

request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");

有必要在表单中添加“acceptcharset”

<form method="post" enctype="multipart/form-data" acceptcharset="UTF-8" > 

运行JVM

-Dfile.encoding=UTF-8

如果您使用 response.setCharacterEncoding() 在 HTTP 标头中发送 HTML 元标记,则不需要它。

如果有人在使用 Grails(或纯 Spring)Web 应用程序时偶然发现了这个问题,以下是对我有帮助的帖子:

http://forum.spring.io/forum/spring-projects/web/2491-solved-character-encoding-and-multipart-forms

为了将多部分请求的默认编码设置为 UTF-8(而不是 ISO-8859-1),我在 resources.groovy(Spring DSL)中添加了以下代码:

multipartResolver(ContentLengthAwareCommonsMultipartResolver) {
    defaultEncoding = 'UTF-8'
}

我正在使用org.apache.commons.fileupload.servlet.ServletFileUpload.ServletFileUpload(FileItemFactory)并在读出参数值时定义编码:

List<FileItem> items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);

for (FileItem item : items) {
    String fieldName = item.getFieldName();

    if (item.isFormField()) {
        String fieldValue = item.getString("UTF-8"); // <-- HERE

过滤器是 IE 的关键。 需要检查的其他一些事项;

什么是页面编码和字符集? 两者都应该是 UTF-8

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

元标记中的字符集是什么?

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

您的 MySQL 连接字符串是否指定了 UTF-8? 例如

jdbc:mysql://127.0.0.1/dbname?requireSSL=false&useUnicode=true&characterEncoding=UTF-8

我正在使用带有 glassfish 和 SQL Server 的 Primefaces。

就我而言,我在后端创建了 Webfilter,以获取每个请求并转换为 UTF-8,如下所示:

package br.com.teste.filter;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;

@WebFilter(servletNames={"Faces Servlet"})
public class Filter implements javax.servlet.Filter {

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        request.setCharacterEncoding("UTF-8");
        chain.doFilter(request, response);      
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // TODO Auto-generated method stub      
    }

}

在视图 (.xhtml) 中,我需要像 @Kevin Rahe 一样将 enctype 参数表的形式设置为 UTF-8:

    <h:form id="frmt" enctype="multipart/form-data;charset=UTF-8" >
         <!-- your code here -->
    </h:form>  

我有同样的问题。 唯一对我有用的解决方案是将 <property = "defaultEncoding" value = "UTF-8"> 添加到 spring 配置文件中的 multipartResoler。

您还必须确保 web.xml 中的编码过滤器 (org.springframework.web.filter.CharacterEncodingFilter) 在多部分过滤器 (org.springframework.web.multipart.support.MultipartFilter) 之前映射。

过滤器和设置 Tomcat 以支持 UTF-8 URI 仅在您通过 URL 的查询字符串传递时才重要,就像使用 HTTP GET 一样。 如果您使用 POST,在 HTTP 消息的正文中带有查询字符串,那么重要的是请求的内容类型,这取决于浏览器将内容类型设置为 UTF-8 和发送具有该编码的内容。

真正做到这一点的唯一方法是通过将每个响应的 Accept-Charset 标头设置为“UTF-8;q=1,ISO-8859-1;q=0.6”来告诉浏览器您只能接受 UTF-8 . 这将使 UTF-8 成为最佳质量,默认字符集 ISO-8859-1 可以接受,但质量较低。

说文件名乱码,是不是在HttpServletRequest.getParameter的返回值里面乱码了?

我想我迟到了,但是当你使用野蝇时,你可以向 standalone.xml 添加一个默认编码。 只需在 standalone.xml 中搜索

<servlet-container name="default"> 

并添加这样的编码:

<servlet-container name="default" default-encoding="UTF-8">

为了避免手动将所有请求参数转换为 UTF-8,您可以在控制器中定义一个用@InitBinder注释的方法:

@InitBinder
protected void initBinder(WebDataBinder binder) {
    binder.registerCustomEditor(String.class, new CharacterEditor(true) {
        @Override
        public void setAsText(String text) throws IllegalArgumentException {
            String properText = new String(text.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
            setValue(properText);
        }
    });
}

以上将在定义它的控制器中自动将所有请求参数转换为UTF-8。

您不使用 UTF-8 来编码 HTML 表单的文本数据。 html 标准定义了两种编码,该标准的相关部分在这里 “旧”编码,而不是处理 ascii,是 application/x-www-form-urlencoded。 新的可以正常工作的是 multipart/form-data。

具体来说,表单声明如下所示:

 <FORM action="http://server.com/cgi/handle"
       enctype="multipart/form-data"
       method="post">
   <P>
   What is your name? <INPUT type="text" name="submit-name"><BR>
   What files are you sending? <INPUT type="file" name="files"><BR>
   <INPUT type="submit" value="Send"> <INPUT type="reset">
 </FORM>

我认为这就是你所需要担心的——网络服务器应该处理它。 如果您正在编写直接从 Web 客户端读取 InputStream 的内容,那么您将需要阅读RFC 2045RFC 2046

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM