为什么我在 Android 上传文件到 NanoHTTPD 服务器时出现中文文件名的乱码?

Why do I get messy code of chinese filename when I upload files to NanoHTTPD server in Android?

我在我的 Android 应用程序中使用 NanoHTTPD 作为 Web 服务器,我使用代码 A 将多个文件包括中文文件名上传到服务器客户端。

但是我在Code B中得到中文文件名的乱码,我该如何解决这个问题?谢谢!

乱码截图

代码A

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>WiFi File Transfer</title>
    <meta charset= "utf-8"/>  
</head>

<body>
        <div id="content">     

            <form action="" method="post" enctype="multipart/form-data">
                <input type="file" name="myupload" multiple="multiple" />
                <input type="submit" value="Upload Files"/>
            </form>                                       


        </div> 

</body>
</html>

代码B

@Override
public Response serve(IHTTPSession session) {

        String uri = session.getUri();

        MURLPar mURLPar=new  MURLPar(mContext);
        SetMURLParValue(mURLPar,session);

        Method method = session.getMethod();
        if (Method.POST.equals(method)) {

            Map<String, String> files=null;
            try {

                files = new HashMap<String, String>();
                session.parseBody(files);
            }catch (Exception e) {                
            }


            ActionUploadFiles(mURLPar,files,session);
            ...

}      


 private void ActionUploadFiles(MURLPar mURLPar, Map<String, String> files,IHTTPSession session){
        File upload = new File(FileFolderHelper.GetPhysicsCurrentPath(mURLPar) +"/Upload");

        try{
            Set<String> keys = files.keySet();

            for (String key:keys) {
                String location = files.get(key);
                File source = new File(location);
                String filename=session.getParms().get(key);

                //It will be messy code when uploaded filename is chinese!    
                filename=java.net.URLDecoder.decode(filename, "utf-8"); 

                File target = new File(upload.getPath(),filename);

                FileUtils.copyFile(source,target);
            }
        }
        catch (Exception e) {
            Utility.LogError("Upload Error: "+ e.getMessage());
        }

    }      

文件名未 URL 编码。 NanoHTTPD 在 Content-Type header 中查找 charset 指令。 不幸的是,对于 multipart/form-data,唯一有效的指令似乎是 boundary, 并且 NanoHTTPD 退回到 ASCII。

除了修改NanoHTTPD的ContentType.getEncoding()方法外,我能想到的唯一解决方法是:

  1. 添加accept-charset="UTF-8"确保表单编码。

    <div id="content">
        <form action="" method="post" enctype="multipart/form-data" accept-charset="UTF-8">
            <input type="file" name="myupload" multiple="multiple" />
            <input type="submit" value="Upload Files"/>
       </form>
    

  2. 在解析内容之前将字符集指令添加到 NanoHTTPD session,ContentType class 有一个方法可以做到这一点:

    @Override
    public Response serve(IHTTPSession session) {
        // add "; charset=UTF-8" to the content type
        ContentType ct = new ContentType(session.getHeaders().get("content-type")).tryUTF8();
        session.getHeaders().put("content-type", ct.getContentTypeHeader());
    
        ...
    
        // no need to URL decode
        String filename=session.getParms().get(key);