gpt4 book ai didi

java - 使用 HTTPHandler 上传文件

转载 作者:行者123 更新时间:2023-12-01 19:34:10 25 4
gpt4 key购买 nike

我正在尝试使用 HTTPHandler 上传文件(多部分表单数据)。

WebKit Boundary 正在写入目标文件,从而损坏文件。

输入文件可以是任何类型的文件,包括文本、zip、apk 等。

代码:

    public void handle(HttpExchange httpExchange) throws IOException {

URI uri = httpExchange.getRequestURI();
String httpReqMethod = httpExchange.getRequestMethod();
Headers headers = httpExchange.getRequestHeaders();
InputStream inputStrm = null;
FileOutputStream destFile = null;
String contentType = ((headers.get("Content-type") != null) ? (headers.get("Content-type").toString()) : (null));
httpExchange.getRequestURI().getQuery());

Map<String, String> queryParams = queryToMap(httpExchange.getRequestURI().getQuery());
Set<String> keys= headers.keySet();
Iterator<String> itr = keys.iterator();
while(itr.hasNext())
{
String key = (String)itr.next();
}

File file = new File(ACEConstants.WEB_SERVER_CTX_ROOT + uri.getPath()).getCanonicalFile();
String resource = uri.getPath().substring(
uri.getPath().indexOf(ACEConstants.WEB_SERVER_CTX_ROOT)+ACEConstants.WEB_SERVER_CTX_ROOT.length()+1);

if(httpReqMethod.equals(ACEConstants.HTTP_REQUEST_METHOD_POST) )
{
if(contentType != null && contentType.contains("multipart/form-data"))
{
if(resource.equals("fileUpload"))
{
inputStrm = httpExchange.getRequestBody();
destFile = new FileOutputStream(new File("D:\\"+queryParams.get("fileName")));
String contentLength = headers.get("Content-length").toString();
long fileSize = (Long.parseLong(contentLength.substring(1, contentLength.length()-1)));
int iteration = 1;
long bytesToBeRead = (fileSize > 1024) ? ((iteration * 1024)) : (inputStrm.available());
long bytesRemaining = (fileSize) - (iteration * 1024);
byte[] bytes = new byte[1024];

if(fileSize <= 1024)
{
bytes = new byte[inputStrm.available()];
inputStrm.read(bytes);
destFile.write(bytes);
}
else {

while (inputStrm.read(bytes) != -1) {
iteration++;
destFile.write(bytes);
bytesRemaining = ( fileSize - ((iteration-1) * 1024));
if (bytesRemaining >= 1024) {
bytesToBeRead = 1024;
bytes = new byte[1024];
}
else {
bytes = new byte[inputStrm.available()];

inputStrm.read(bytes);
destFile.write(bytes);
break;
}
}
}
destFile.close();
}
}
}
}

这是 HTML 代码

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script type="text/javascript">

function processForm(frm)
{
var fu1 = document.getElementsByName("datafile");
var filename = fu1[0].value;
filename = filename.substring(filename.lastIndexOf("\\")+1);
alert("You selected " + filename);
frm.action = "http://localhost:64444/ACE/fileUpload?fileName="+filename;
return true;
}

</script>
</head>
<body>

<form name="myForm" enctype="multipart/form-data" method="post" acceptcharset="UTF-8" onsubmit="processForm(this);">
<p>
Please specify a file, or a set of files:<br>
<input type="file" name="datafile" size="40">
</p>
<div>
<input type="submit" value="Send">
</div>
</form>

</body>
</html>

这里出了什么问题?非常感谢您的帮助。

编辑1:

如果输入文件是包含文本的文本文件:1234567890
输出文件有内容:

 ------WebKitFormBoundaryKBRUiUWrIpW9wq2j
Content-Disposition: form-data; name="textline"


------WebKitFormBoundaryKBRUiUWrIpW9wq2j
Content-Disposition: form-data; name="datafile"; filename="test.txt"
Content-Type: text/plain

1234567890
------WebKitFormBoundaryKBRUiUWrIpW9wq2j--

最佳答案

如何使用HttpHandler上传文件

文件上传到 HttpHandler 会导致边界和其他 MIME 信息写入请求内容。由于解析此信息非常复杂且容易出错,因此可以求助于使用 Commons FileUpload事实证明,它在经典的 Servlet 环境中非常有效。

考虑这个带有自定义ContextRequest的示例。这将处理通过 multipart/form-data 添加到请求正文中的所有边界解析,同时仍然允许您保留 HttpHandler 接口(interface)。

主要思想包括实现自己版本的 ContextRequest 来处理 HttpHandler 中提供的数据:

   public HttpHandlerRequestContext implements RequestContext {

private HttpExchange http;

public HttpHandlerRequestContext(HttpExchange http) {
this.http = http;
}

@Override
public String getCharacterEncoding() {
//Need to figure this out yet
return "UTF-8";
}

@Override
public int getContentLength() {
//tested to work with 0 as return. Deprecated anyways
return 0;
}

@Override
public String getContentType() {
//Content-Type includes the boundary needed for parsing
return http.getRequestHeaders().getFirst("Content-type");
}

@Override
public InputStream getInputStream() throws IOException {
//pass on input stream
return http.getRequestBody();
}
}

供引用:这是一个列出收到的文件的工作示例。

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.util.List;
import java.util.Map.Entry;

import org.apache.commons.fileupload.FileItem;

import org.apache.commons.fileupload.RequestContext;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;

public class HttpServerTest {

public static void main(String[] args) throws Exception {
HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
server.createContext("/fileupload", new MyHandler());
server.setExecutor(null); // creates a default executor
server.start();
}

static class MyHandler implements HttpHandler {
@Override
public void handle(final HttpExchange t) throws IOException {
for(Entry<String, List<String>> header : t.getRequestHeaders().entrySet()) {
System.out.println(header.getKey() + ": " + header.getValue().get(0));
}
DiskFileItemFactory d = new DiskFileItemFactory();

try {
ServletFileUpload up = new ServletFileUpload(d);
List<FileItem> result = up.parseRequest(new RequestContext() {

@Override
public String getCharacterEncoding() {
return "UTF-8";
}

@Override
public int getContentLength() {
return 0; //tested to work with 0 as return
}

@Override
public String getContentType() {
return t.getRequestHeaders().getFirst("Content-type");
}

@Override
public InputStream getInputStream() throws IOException {
return t.getRequestBody();
}

});
t.getResponseHeaders().add("Content-type", "text/plain");
t.sendResponseHeaders(200, 0);
OutputStream os = t.getResponseBody();
for(FileItem fi : result) {
os.write(fi.getName().getBytes());
os.write("\r\n".getBytes());
System.out.println("File-Item: " + fi.getFieldName() + " = " + fi.getName());
}
os.close();

} catch (Exception e) {
e.printStackTrace();
}
}
}
}

关于java - 使用 HTTPHandler 上传文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59237193/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com