【问题标题】:Uploading files with filenames which include unicode characters won't work上传文件名包含 unicode 字符的文件将不起作用
【发布时间】:2016-07-22 07:10:56
【问题描述】:

我正在尝试从 html 表单上传文件。我为它编写了一个 servlet,它应该在接收到的部分上打开一个输入流,并将数据写入一个具有相同名称和扩展名的文件中。 首先,我遇到了数据本身的问题。例如,具有 unicode 正文的文本文件无法使用 UTF-8 正确编码字符。然后我开始使用 DataInputStream 和 DataOutputStream 并且由于某种原因现在可以正常工作。剩下的是文件名的问题。如果并且当文件名包含 unicode 字符时,文件名本身将没有正确的编码,并且会出现一些奇怪的字符(如预期的那样)。我已经尝试了几件事,但我不知道如何解决它。我正在使用 Wildfly 10.0.10.Final。 因此,例如,如果我的文件名为 ááéé.txt,则生成的文件名为 ááéé.txt。

这是我的 HTML 页面:

<html>
<h:head>        
    <meta charset="UTF-8" />
    <meta content="text/html" />
</h:head>
<h:body>
    <div class="container">
        Upload a new file:
        <form enctype="multipart/form-data" method="post" action="upload">
        Files: <input multiple="multiple" id="fileUpload" type="file" name="files" />
        <input type="submit" multiple="multiple" value="upload" />
    </form>
    </div>   
</h:body>
</html>

我的servlet是这样写的:

@WebServlet(name = "fileUploadServlet", urlPatterns = {"/upload"})
@MultipartConfig
public class FileUploadServlet extends HttpServlet {    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        int n = 0;
        for (Part file : req.getParts()) {
            String fileName = new String(file.getSubmittedFileName().getBytes("UTF-8"), "UTF-8");            
            try (DataInputStream dis = new DataInputStream(file.getInputStream());
                 DataOutputStream dos = new DataOutputStream(new FileOutputStream("E:\\upload\\" + fileName))) {
                byte[] buffer = new byte[1024];
                int r;
                while ((r = dis.read(buffer)) != -1) {
                    dos.write(buffer, 0, r);
                }
                n++;
            }
        }
        resp.getWriter().print(n + " files uploaded.");
    }
}

提前致谢!

【问题讨论】:

  • String fileName = new String(file.getSubmittedFileName().getBytes("UTF-8"), "UTF-8");String fileName = file.getSubmittedFileName();完全相同。您正在将字符串转换为字节,然后再转换回字符,所有这些都使用相同的字符集,实际上是身份往返操作。不过,我确实发现 req.setCharacterEncoding("UTF-8") 的使用很可疑。 HTTP 请求发送自己的编码是有原因的;你不应该覆盖它。
  • 但我猜编码不是UTF-8?
  • 可能不会。浏览器不必使用用于编码 HTML 的相同字符集发送数据。
  • 如何修改这种行为?
  • 您不需要这样做。如果删除 req.setCharacterEncoding("UTF-8") 行,提交的文件名是什么样的?

标签: java servlets jakarta-ee unicode servlet-3.0


【解决方案1】:

似乎 WildFly 实现不使用请求的字符编码。 我找到了解决方案:

String filename = new String(part.getSubmittedFileName().getBytes("ISO-8859-1"), "UTF-8");

【讨论】:

    【解决方案2】:

    req.setCharacterEncoding(...) 有时不起作用。

    如果您使用的是 Tomcat,请在 server.xml 中的 Connector 部分设置 URIEncoding="UTF-8",例如

    <Connector port="80" protocol="HTTP/1.1" maxThreads="150" connectionTimeout="20000" enableLookups="false"
        URIEncoding="UTF-8" redirectPort="443" />
    

    我猜 Wildfly 中可能有类似的设置。

    【讨论】:

      猜你喜欢
      • 2018-09-21
      • 2021-01-08
      • 2012-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多