We usually always do is upload files, folders and upload files to upload similar, but there are some differences, this did upload folder on the record for future use after the next.
The project needs:
Support for large files and upload resume, resume required to support all browsers, including ie6, ie7, ie8, ie9, Chrome, Firefox, 360 security browser and refresh the browser still be able to resume, restart your browser (close your browser and open) can still continue to upload, you restart the computer and still be able to upload
Supports folder upload, requires the server to retain a hierarchical structure, and can resume. The need to support more than 100,000 folder upload.
Support low version of the system and the browser, because the project's final operating environment in the government, the government of configurations in general, are office staff, memory is not large, basically a Windows XP-based system.
1. Introduction enctype
Enctype attribute specifies how it should be encoded form data before sending it to the server.
enctype function is to inform the server request body MIME type (action request message as the content-type header)
1,1 enctype value of three
value |
description |
application/x-www-form-urlencoded |
Coding all the characters (default) before sending |
multipart/form-data |
Not the character encoding. Each table is divided into a single component |
text/plain |
Spaces converted to "+" plus, but not a special character encoding. |
1. 当enctype=’application/x-www-form-urlencoded’
2.当enctype=’multipart/form-data’
The observation that the body of the request to change. Such a request is called a multi-member body in the request body.
What is a multi-part request body: each table is to be divided into a single member.
In the latter boundary content-type of the request header is a string of random string as the division identifier
Ordinary Form Item:
// name mean value of the name attribute inside a text box, and the value of our admin text input
Content-Disposition: form-data; name="username"
admin
File Form Item
// filename means: We upload the file name, content-Type means: MIME type, asdasdas means: the contents of a file inside
Content-Disposition: form-data; name="upload"; filename="a.txt"
Content-Type: text/plain
asdasdas
3. 当enctype=’text/plain’
w3c said: Spaces will become "+" plus sign, but I did not find here, get only when requested, the space will become a "+" sign
Into the title
Complete the upload need to meet three necessary conditions
Provided form the form, method must be post, because the transmission of data get request is generally 2kb, different browsers is not the same.
Form Properties form must be enctype multipart / form-data
Upload input field to provide input type = "file" category
The principle generally: When the values are enctype multipart / form-data, the browser will each table item is divided, is divided into different parts, is divided at the boundary identification, the identification string is randomly generated Finally, at the end of a divided identification string form item will be two more "- -" represents the end. Get string dividing server request.getHeader ( "content-type"), and then parsed.
Code
First, the development environment to build
Prepare two third-party jar package
All dependencies
Code
<%@ page language="java" import="up6.DBFile" pageEncoding="UTF-8"%>
<%@ page contentType="text/html;charset=UTF-8"%>
<%@ page import="up6.FileBlockWriter" %>
<%@ page import="up6.XDebug" %>
<%@ page import="up6.*" %>
<%@ page import="up6.biz.*" %>
<%@ page import="org.apache.commons.fileupload.FileItem" %>
<%@ page import="org.apache.commons.fileupload.FileItemFactory" %>
<%@ page import="org.apache.commons.fileupload.FileUploadException" %>
<%@ page import="org.apache.commons.fileupload.disk.DiskFileItemFactory" %>
<%@ page import="org.apache.commons.fileupload.servlet.ServletFileUpload" %>
<%@ page import="org.apache.commons.lang.*" %>
<%@ page import="java.net.URLDecoder"%>
<%@ page import="java.util.Iterator"%>
<%@ page import="net.sf.json.JSONObject"%>
<%@ page import="java.util.List"%>
<%
out.clear();
String uid = request.getHeader("uid");//
String id = request.getHeader("id");
String lenSvr = request.getHeader("lenSvr");
String lenLoc = request.getHeader("lenLoc");
String blockOffset = request.getHeader("blockOffset");
String blockSize = request.getHeader("blockSize");
String blockIndex = request.getHeader("blockIndex");
String blockMd5 = request.getHeader("blockMd5");
String complete = request.getHeader("complete");
String pathSvr = "";
// parameter is empty
if( StringUtils.isBlank( uid )
|| StringUtils.isBlank( id )
|| StringUtils.isBlank( blockOffset ))
{
XDebug.Output("param is null");return;
}
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List files = null;
try {files = upload.parseRequest(request);}
catch (FileUploadException e)
{out.println("read file data error:" + e.toString());return;}
FileItem rangeFile = null;
Iterator fileItr = files.iterator();
while (fileItr.hasNext())
{
rangeFile = (FileItem) fileItr.next();
if(StringUtils.equals( rangeFile.getFieldName(),"pathSvr"))
{
pathSvr = rangeFile.getString();
pathSvr = PathTool.url_decode(pathSvr);
}
}
boolean verify = false;
String msg = "";
String md5Svr = "";
long blockSizeSvr = rangeFile.getSize();
if(!StringUtils.isBlank(blockMd5)){md5Svr = Md5Tool.fileToMD5(rangeFile.getInputStream());}
verify = Integer.parseInt(blockSize) == blockSizeSvr;
if(!verify){ msg = "block size error sizeSvr:" + blockSizeSvr + "sizeLoc:" + blockSize;}
if(verify && !StringUtils.isBlank(blockMd5))
{
verify = md5Svr.equals(blockMd5); if(!verify) msg = "block md5 error";
}
if(verify)
{
FileBlockWriter res = new FileBlockWriter();
if( Integer.parseInt(blockIndex)==1) res.CreateFile(pathSvr,Long.parseLong(lenLoc));
res.write( Long.parseLong(blockOffset),pathSvr,rangeFile);
up6_biz_event.file_post_block(id,Integer.parseInt(blockIndex));
JSONObject o = new JSONObject();
o.put("msg", "ok");
o.put("md5", md5Svr);
o.put("offset", blockOffset);
msg = o.toString();
}
rangeFile.delete();
out.write(msg);
%>
Download a necessary condition
A first two streams
content-type
Content-Type is very important to return the message content, represents the content of the document belongs to what MIME type.
The browser will decide how to display the returned message body content based on Content-Type.
The default value is text / html
You can use request.getServletContext (). GetMimeType ( "filename") to obtain the MIME type.
Content-Disposition
Content-disposition is an extension to the MIME protocol, MIME protocol indicates MIME user agent how to display the attached file.
The default value is inline, means open in a browser window.
When the server sends the file to the client's browser, if the browser supports the file type, generally use the default browser to open, such as txt, jpg, etc., will be displayed directly in the browser.
If you need to prompt the user to save, use Content-Disposition conduct some processing, the key is to be sure to add attachment.
For example: Content-Disposition: attachment; filename = xxx, the browser will activate the download dialog box, attachment representation annex, followed filname followed by the file name is displayed in the download box.
flow
Download is the response to the client bytes of data! Will become a file byte array, using response.getOutputStream ()
To respond to the browser.
The following code, the code has been implemented HTTP functionality, users can pause the download process, and continue to download, resulting in pressure on the server is relatively small.
String fid = request.getHeader("id");
String blockIndex = request.getHeader("blockIndex");//基于1
String blockOffset = request.getHeader ( "blockOffset"); // block offset, relative to the entire file
String blockSize = request.getHeader ( "blockSize"); // block size (the size of the current to be downloaded)
String pathSvr = request.getHeader ( "pathSvr"); // file in the server's location
pathSvr = PathTool.url_decode(pathSvr);
if ( StringUtils.isBlank(fid)
||StringUtils.isBlank(blockIndex)
||StringUtils.isEmpty(blockOffset)
||StringUtils.isBlank(blockSize)
||StringUtils.isBlank(pathSvr))
{
response.setStatus(500);
response.setHeader ( "err", "parameter is null");
return;
}
File f = new File(pathSvr);
//file does not exist
if(!f.exists())
{
response.setStatus(500);
OutputStream os = response.getOutputStream();
System.out.println (String.format ( "% s file does not exist", pathSvr));
os.close();
return;
}
long fileLen = f.length();
response.setContentType("application/x-download");
response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","no-cache");
response.addHeader("Content-Length",blockSize);
response.setDateHeader("Expires", 0);
OutputStream os = response.getOutputStream();
try
{
RandomAccessFile raf = new RandomAccessFile(pathSvr,"r");
int readToLen = Integer.parseInt(blockSize);
int readLen = 0;
raf.seek (Long.parseLong (blockOffset)); // fix index
byte[] data = new byte[1048576];
while( readToLen > 0 )
{
readLen = raf.read(data,0,Math.min(1048576,readToLen) );
readToLen -= readLen;
os.write(data, 0, readLen);
}
os.flush();
os.close();
raf.close();
os = null;
response.flushBuffer();
out.clear();
out = pageContext.pushBody();
}
catch(Exception e)
{
response.setStatus(500);
os.close();
out.close();
e.printStackTrace ();
}
finally
{
if(os != null)
{
os.close();
os = null;
}
out.clear();
out = pageContext.pushBody();
}%>
Load the file list, displayed in the download list
Most of the back-end code logic is the same, currently supports MySQL, Oracle, SQL. Before using the need to configure the database, you can refer me to write this article: http://blog.ncmem.com/wordpress/2019/08/12/java-http%E5%A4%A7%E6%96%87 % E4% BB% B6% E6 % 96% AD% E7% 82% B9% E7% BB% AD% E4% BC% A0% E4% B8% 8A% E4% BC% A0 /
Welcome to the discussion group "374 992 201" together