我在Java桌面环境中使用NanoHTTPD webserver 2.1.0。 (没有Android)
一切正常......但不是使用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;
}
}
以下是问题所在: 临时文件不存在。现有的另一个临时文件具有不同的“数字”,这似乎是正确的文件,因为内容与上传文件的内容相同。那么如何获得正确的temp-filename?
另一个问题是: 临时文件包含漏洞POST内容:
-----------------------------115801144322347
Content-Disposition: form-data; name="file"; filename="filename.txt"
Content-Type: application/octet-stream
-->content of the uploaded file
-----------------------------115801144322347--
如果内容是pic或二进制文件,则会出现此问题。
看来NanoHTTPD不会对POST请求做任何特殊操作。它总是一样...将请求保存到tmp文件并提供页面。 所以: - 如何获取正确的临时文件? - &GT;我认为这是一个错误。我得到了正确的路径和名称,但“数字”已被破坏。 idk ...如果发生上传,我应该暂时更改java tmp-path,然后始终删除该文件。那么我只有一个tmp文件独立于任何命名? - 如何从文件
中删除html请求标头或者我做错了什么?这是将文件上传到nanohttpd的正确方法吗?
谢谢你的帮助!答案 0 :(得分:4)
我在发布“你找到了解决办法吗?”后不久就想通了。问题,但忘记发布,直到你今天回复。
<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”。
希望有所帮助!
答案 1 :(得分:1)
老问题!但是我一直在寻找解决这个问题的方法。我在处理IHTTPSession
输入流时遇到问题。事实证明,在读取流时,该流将过早耗尽,并且您必须返回以获取更多信息。这是在我发送application/octet-stream
大于500k的数据时发生的(我没有提供确切的数字)。
我的解决方案是打开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\"]");
}
我希望这会有所帮助。