java – 使用HTTPHandler上传文件
发布时间:2020-12-15 04:30:53 所属栏目:Java 来源:网络整理
导读:我正在尝试使用HTTPHandler上传文件(多部分表单数据). WebKit Boundary正在写入目标文件,从而破坏文件. 输入文件可以是任何类型的文件,包括文本,zip,apk等. 码: public void handle(HttpExchange httpExchange) throws IOException { URI uri = httpExchang
我正在尝试使用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接口. 主要思想包括实现一个自己的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("rn".getBytes()); System.out.println("File-Item: " + fi.getFieldName() + " = " + fi.getName()); } os.close(); } catch (Exception e) { e.printStackTrace(); } } } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |