【问题标题】:NanoHTTPD: upload a file using a html form (POST)NanoHTTPD:使用 html 表单 (POST) 上传文件
【发布时间】:2014-07-21 14:33:34
【问题描述】:

我在 Java 桌面环境中使用 NanoHTTPD 网络服务器 2.1.0。 (没有安卓)

一切正常...但不是使用 POST 方法上传文件(表单不支持 PUT)

这是我的 HTML 代码:

<form method="post" enctype="multipart/form-data">
    choose a file<br>
    <input name="file" type="file" size="50" maxlength="100000"">
    <button type="submit">upload</button>
</form>

这是我的服务器方法:

public Response serve(IHTTPSession session) {
    if (session.getMethod() == Method.POST) {
        Map<String, String> files = new HashMap<String, String>();
        session.parseBody(files);
        //this prints {file=C:\path-to-java-tmp-files\NanoHTTPD-4635244586997909485}
        //the number is always different
        System.out.println(files.toString());
    } else {
        //page containing the index.html including the form
        return page;
    }
}

这就是问题所在: 临时文件不存在。存在另一个带有不同“数字”的临时文件,这似乎是正确的文件,因为内容与上传文件的内容相同。那么如何获取正确的临时文件名呢?

另一个问题是: 临时文件包含漏洞 POST 内容:

-----------------------------115801144322347
Content-Disposition: form-data; name="file"; filename="filename.txt"
Content-Type: application/octet-stream

-->content of the uploaded file


-----------------------------115801144322347--

如果内容是图片或二进制,这是一个问题。

似乎 NanoHTTPD 对 POST 请求没有任何特殊作用。它总是一样的......将请求保存到 tmp 文件并提供页面。 所以: - 如何获得正确的临时文件? --> 我认为这是一个错误。我得到了正确的路径和名称,但“数字”已损坏。 idk ...如果发生上传,我是否应该临时更改java tmp-path,然后总是删除文件。那么我只有一个独立于任何命名的 tmp 文件吗? - 如何杀死文件中的html请求头

还是我做错了什么?这是将文件上传到 nanohttpd 的正确方法吗?

感谢您的帮助!

【问题讨论】:

  • 我知道您在 7 月发布了帖子,但您找到解决方案了吗?我收到损坏的 PNG 文件,因为 NanoHttpd 甚至对二进制文件也使用 readLine()
  • 不客气。我没有找到解决方案:(我只是放弃了。

标签: java html nanohttpd


【解决方案1】:

老问题!但我正在寻找解决这个问题的方法。我在处理IHTTPSession 输入流时遇到问题。事实证明,当阅读它时,流会过早地变空,你必须返回更多。这发生在我发送大于约 500k 的 application/octet-stream 数据时(我没有给出确切的数字)。

我的解决方案是打开IHTTPSession输入流,并迭代读取输入流,直到它完全耗尽:

public Response post_upload(IHTTPSession session) {   
    System.out.println("received HTTP post with upload body...");  
    int streamLength = Integer.parseInt(session.getHeaders().get("content-length"));
    System.out.println("Content length is: " + streamLength);
    byte[] fileContent = new byte[streamLength];
    try {
        InputStream input = session.getInputStream();
        int bytesRead = 0;
        int iterations = 0;
        while (bytesRead < streamLength) {              
            int thisRead = input.read(fileContent, bytesRead, streamLength-bytesRead);                
            bytesRead += thisRead;
            iterations++;
        }
        System.out.println("Read " + bytesRead + " bytes in " + iterations + " iterations.");
    }
    catch (Exception e) {
        System.out.println("We have other problems...");
    }
    return newFixedLengthResponse(Response.Status.OK, "application/json", "[\"no prob\"]");
}

我希望这会有所帮助。

【讨论】:

  • 谢谢伙计。你保存了我的项目。是使用 InputStream input = session.getInputStream();以错误的方式,这就是为什么响应错误 400 错误的原因。使用您的输入流方法后,我的问题解决了。谢谢!!!!!!!!!
【解决方案2】:

我在发布“您找到解决方法了吗?”后不久就发现了这一点。问题,但在您今天回复之前忘记发布。

<form method="post" enctype="multipart/form-data" action="http://whatever.com/path/">
    <input type="file" name="file" />
    <input type="hidden" name="extra_data" value='blah blah blah' />
    <input type="submit" value="Send" />
</form>

还有 Java 代码:

if (session.getMethod() == Method.POST) {
    try { session.parseBody(files); }
    catch (IOException e1) { e1.printStackTrace(); }
    catch (ResponseException e1) { e1.printStackTrace(); }

    extraData = session.getParms().get("extra_data");
    File file = new File(files.get("file"));
}

重要的是您发送的数据带有文件数据、文件名和文件 mime 类型。

就我而言,我使用 python 请求进行 POST 并且没有向其发送足够的数据。正确的帖子结构是:

file_data = { 'file': ('test.png', open('../some_file.png', 'rb'), 'image/png') }
requests.post("http://whatever.com/path", data = { 'extra_data': "blah blah blah" }, files = file_data)

上面的代码从“some_file.png”读取,但是告诉服务器它叫做“test.png”。

希望有帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-01
    • 2010-12-05
    • 2015-06-20
    • 2012-08-29
    • 2017-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多