What we usually do is to upload files. Uploading folders is similar to uploading files, but there are also some differences. This time, we will record the uploaded folder for later use.

Requirements of this project:

Support large file upload and continuingly, continuingly support all browsers, including ie6, ie7 and ie8, ie 9, Chrome, Firefox, 360 secured browser, and can still continuingly after refresh the browser, restart your browser (close the browser and then open) still can continue to upload, after restart the computer will still be able to upload

Support folder upload, requiring the server to preserve the hierarchy, and be able to continue. Need to support more than 100,000 folder upload.

Support low version of the system and browser, because the final operation environment of this project is in the government, the configuration of the government is general, staff are used for office, the memory is not large, basically based on Windows XP system.

1. Introduce EncType

The encType attribute specifies how form data should be encoded before being sent to the server.

Enctype tells the server the MIME type of the request body (the request header content-type does the same thing).

1, 1 There are three values of encType

value

describe

application/x-www-form-urlencoded

Encodes all characters before sending (default)

multipart/form-data

No character encoding. Each form item is split into a part

text/plain

Spaces are converted to “+” plus signs, but no special character encoding.

1. When the enctype = “application/x – WWW – form – urlencoded ‘

2. When the enctype = “multipart/form – data ‘

Just by looking at this, the body of the request has changed. This request body is called the multi-part request body.

What is a multi-part request body? It splits each form item into a part.

A random string following the content-type boundary of the request header is used as the partition identifier

Common form items:

// Name means the name attribute value in the text box, and admin is the text value we entered

Content-Disposition: form-data; name=”username”

admin

File form item

//filename means the name of the file we uploaded, content-type means the MIME Type, and asdasdas means the content of the file

Content-Disposition: form-data; name=”upload”; filename=”a.txt”

Content-Type: text/plain

asdasdas

3. When the enctype = “text/plain”

The W3C says that Spaces will become “+” + signs, but I don’t see that here, only Spaces will become “+” signs for GET requests

Get into the business

Three conditions must be met to complete the upload

Provide a form. Method must be POST because the transfer data for GET requests is typically 2KB, depending on the browser.

The encType attribute of the form must be multipart/form-data

Provide an upload input field for the input type= “file” class

General implementation principle: When the value of encType is multipart/form-data, the browser will divide each form entry into different parts and use the value of boundary as the segmentation identifier. The character string of this identifier is randomly generated. There will be two more “-” at the end of the segmentation identifier string of the last form entry, representing the end. The server gets the split string with Request. getHeader(” content-type “) and parses it.

Code implementation

I. Construction of development environment

Prepare two third-party JAR packages

Commons – IO package

Commons – upload package

All dependency packages

Code implementation

<%@ 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”%>

The < %

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         = “”;

// The parameter is null

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

% >

Prerequisites for downloading

Two heads and one stream

content-type

The content-type is the very important Content in the return message, indicating what MIME Type the document Content belongs to.

The browser determines how to display the returned message body Content based on the Content-Type.

The default value is text/ HTML

You can use the request. GetServletContext (.) getMimeType (” name “) for the MIME type.

Content-Disposition

Content-disposition is an extension of the MIME protocol that instructs the MIME user agent how to display attached files.

The default is inline, which opens in a browser window.

When the server sends a file to the client browser, if the file type supported by the browser is generally opened by the browser by default, such as TXT and JPG, which will be directly displayed in the browser.

If you need to prompt the user to save, do something with Content-Disposition, and the key is to always include an attachment.

For example: the Content – Disposition: attachment; Filename = XXX, the browser will activate the download dialog box, attachment represents the attachment, filname is followed by the filename displayed in the download box.

flow

Downloading is responding bytes of data to the client! To turn a file into a byte array, use Response.getOutputStream ()

To respond to the browser.

The code is as follows, this code has realized the breakpoint continuation function, the user can pause in the download process, and continue to download, the server caused less pressure.

String fid             = request.getHeader(“id”);

String blockIndex = request.getHeader(“blockIndex”); / / based on 1

String blockOffset = request.getHeader(“blockOffset”); // Block offset relative to the entire file

String blockSize = request.getHeader(“blockSize”); // Block size (current size required to download)

String pathSvr = request.getHeader(“pathSvr”); // The file is located on the server

pathSvr            = PathTool.url_decode(pathSvr);

if (  StringUtils.isBlank(fid)

     ||StringUtils.isBlank(blockIndex)

     ||StringUtils.isEmpty(blockOffset)

     ||StringUtils.isBlank(blockSize)

     ||StringUtils.isBlank(pathSvr))

{

     response.setStatus(500);

Responsetheader (“err”,” parameter 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) ); // Locate the 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 file list, displayed in the download list

The back-end code logic is mostly the same and currently supports MySQL,Oracle, and SQL. Need to configure the database before using, can refer to me to write this article: blog.ncmem.com/wordpress/2…

Welcome to join the group to discuss “374992201”