使用HTTPHandler进行文件上传

我正在尝试使用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 queryParams = queryToMap(httpExchange.getRequestURI().getQuery()); Set keys= headers.keySet(); Iterator 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) { bytesToBeRead = 1024; bytes = new byte[1024]; } else { bytes = new byte[inputStrm.available()]; inputStrm.read(bytes); destFile.write(bytes); break; } } } destFile.close(); } } } } 

这是HTML代码

       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; }    

Please specify a file, or a set of files:

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

编辑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 ,它已被certificate在经典Servlet环境中运行良好。

考虑使用自定义ContextRequest此示例。 这将处理由multipart/form-data添加到请求体中的边界的所有解析,同时仍然允许您保留HttpHandler接口。

主要思想包括实现一个自己的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> header : t.getRequestHeaders().entrySet()) { System.out.println(header.getKey() + ": " + header.getValue().get(0)); } DiskFileItemFactory d = new DiskFileItemFactory(); try { ServletFileUpload up = new ServletFileUpload(d); List 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(); } } } } 

我遇到同样的问题请使用Apache httpClient API为它提供最好的api连接URL(文件上传和处理多部分表单数据)