繁体   English   中英

Java for Web-编码错误的Multipart / form-data文件

[英]Java for Web - Multipart/form-data file with wrong encoding

我正在使用Java和Tomcat 8开发Web应用程序。此应用程序有一个页面用于上传文件,该文件的内容将显示在另一个页面中。 简单明了。

但是,这些文件可能包含不太常用的字符作为其文本的一部分。 现在,我正在使用一个包含越南文字的文件。

该文件以UTF-8编码,可以在任何文本编辑器中打开。 但是,尽管进行了大量搜索和尝试了许多不同的工作,但我找不到任何方法来上传它并使内容保持正确的编码。

我上传文件的页面包含以下格式:

<form method="POST" action="upload" enctype="multipart/form-data" accept-charset="UTF-8" >
                                File: <input type="file" name="file" id="file"  multiple/><br/>
                                Param1: <input type="text" name="param1"/> <br/>
                                Param2: <input type="text" name="param2"/> <br/>
                                <input type="submit" value="Upload" name="upload" id="upload" />
                            </form>

它还包含:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
...
<meta http-equiv="content-type" content="text/html; charset=UTF-8">

我的servlet看起来像这样:

protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        try {
            response.setContentType("text/html;charset=UTF-8");
            request.setCharacterEncoding("UTF-8");

            String param1 = request.getParameter("param1");

            String param2 = request.getParameter("param2");

            Collection<Part> parts = request.getParts();

            Iterator<Part> iterator = parts.iterator();
            while (iterator.hasNext()) {
                Part filePart = iterator.next();
                InputStream filecontent = null;

                filecontent = filePart.getInputStream();

                String content = convertStreamToString(filecontent, "UTF-8");

                //Save the content and the parameters in the database

                if (filecontent != null) {
                    filecontent.close();
                }
            }

        } catch (ParseException ex) {
        } 
    }

static String convertStreamToString(java.io.InputStream is, String encoding) {
        java.util.Scanner s = new java.util.Scanner(is, encoding).useDelimiter("\\A");
        return s.hasNext() ? s.next() : "";
    }

尽管我付出了所有努力,但我始终无法获得保留了正确字符的“内容”字符串。 当正确的应该是“Kạn”时,我得到的像是“ K?n”或“Káºn”(似乎是ISO-8859-1的解释)。

更严重的是,如果我在其他表单参数(param1或param2)中写越南语字符(也需要这样做),则只有将表单的accept-charset和servlet扫描程序编码都设置为ISO-8859-1,我绝对不理解。 在这种情况下,如果我打印接收到的参数,则会得到类似“ K&#7 8 4 1; n”(不带空格)的信息,其中包含正确字符的表示形式。 因此,似乎可以使用ISO-8859-1从表单读取越南语字符,只要表单本身使用该字符集即可。 但是,它永远无法处理上传文件的内容。 我什至尝试将文件编码为ISO-8859-1,以将字符集用于所有内容,但它根本无法工作。

我确信这种情况并非罕见,所以我想向以前可能曾来过那里的人们寻求帮助。 我可能缺少了一些东西,因此可以提供任何帮助。

先感谢您。


编辑1:尽管此问题尚未得到答复,但我会继续发布我的发现,以防有人感兴趣或关注它。

在尝试了许多不同的方法之后,我似乎已经缩小了问题的起因。 我创建了一个类,该类从磁盘上的特定文件夹中读取文件并打印其内容。 代码如下:

public static void openFile() {
    System.out.println(String.format("file.encoding: %s", System.getProperty("file.encoding")));
    System.out.println(String.format("defaultCharset: %s", Charset.defaultCharset().name()));

    File file = new File(myFilePath);
    byte[] buffer = new byte[(int) file.length()];
    BufferedInputStream f = null;
    String content = null;
    try {
        f = new BufferedInputStream(new FileInputStream(file));
    } catch (FileNotFoundException ex) {
    }

    try {
        f.read(buffer);
        content = new String(buffer, "UTF-8");
        System.out.println("UTF-8 File: " + content);
        f.close();
    } catch (IOException ex) {
    }
}

然后,我向此类添加了一个主要函数,使其可执行。 当我独立运行它时,得到以下输出:

file.encoding:UTF-8
defaultCharset:UTF-8
UTF-8文件:{“ ...Kạn...”}

但是,如果按预期的方式将项目作为webapp运行,并从该类中调用相同的函数,则会得到:

file.encoding:Cp1252
默认字符集:Windows-1252
UTF-8文件:{“ ... K?n ...”}

当然,这清楚地表明,Web应用程序用于读取文件的默认编码不是UTF-8。 因此,我对该主题进行了一些研究,找到了为Tomcat创建setenv.bat并执行它的经典答案:

set "JAVA_OPTS=%JAVA_OPTS% -Dfile.encoding=UTF-8"

但是结果仍然不正确:

file.encoding:UTF-8
defaultCharset:UTF-8
UTF-8文件{“ ...Kạn...”}

现在,我可以看到默认编码为UTF-8。 但是,从文件读取的内容仍然是错误的。 上面显示的内容与我在Microsoft Word中打开文件但选择使用ISO-Latin-1而不是UTF-8读取的内容相同。 出于某种奇怪的原因,尽管所有内容都指出使用UTF-8,但读取文件仍可在某处使用ISO-Latin-1。

再次,如果有人对此有建议或指示,将不胜感激。

我似乎无法解决问题,所以让我贡献我找到的答案。

问题在于,调查此类问题非常棘手,因为代码中有很多地方可能需要更改编码(页面,表单编码,请求编码,文件读取,文件编写,控制台输出,数据库编写) ,数据库读取...)。

就我而言,做完我在问题中发布的所有内容之后,我浪费了很多时间试图解决一个不再存在的问题,只是因为我的IDE(该项目的NetBeans)中的控制台输出没有t使用所需的字符编码。 所以我在某种程度上所做的一切正确,但是当我尝试打印任何东西时,我都会弄错。 开始将日志写入文件(而不是控制台)并控制写入编码后,我开始清楚地了解问题。

在问题中已经描述了所有内容之后(在编辑之前),解决方案中缺少的是配置数据库连接的编码。 令我惊讶的是,即使我的数据库和所有表都使用UTF-8,应用程序和MySQL之间的通信仍然在ISO-Latin中。 缺少的最后一件事是向连接添加“ useUnicode = true&characterEncoding = utf-8”,如下所示:

con = DriverManager.getConnection("jdbc:mysql:///dbname?useUnicode=true&characterEncoding=utf-8", "user", "pass");

归功于这个答案,其中包括: https : //stackoverflow.com/a/3275661/843668

暂无
暂无

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

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