Java Server supports source code for resumable data transfer [Support express and thunder]

Source: Internet
Author: User
Tags ranges

The Java Server supports source code for resumable upload (express and Thunder are supported) (only HTTP protocol is supported)

There are many articles on the Internet about Java's support for HTTP resumable upload, but there are few articles about the support for HTTP resumable upload on the Java Server.
This article is the source code of the Java Server that supports HTTP resumable upload, and supports express and thunder.
This article uses a simple Servlet as an example of downloading to support resumable data transfer. After being deployed in a Java Web project, you can use http: // localhost/CdS/HTTP link to call the servlet, which is then downloaded by the express/thunder listener.

Source code of arcsynchttpdownloadservlet:

Package COM. defonds. CDs. common; import Java. io. bufferedoutputstream; import Java. io. file; import Java. io. ioexception; import Java. io. outputstream; import Java. io. randomaccessfile; import javax. servlet. servletexception; import javax. servlet. HTTP. httpservlet; import javax. servlet. HTTP. httpservletrequest; import javax. servlet. HTTP. httpservletresponse; import Org. apache. commons. logging. log; import Org. apache. comm ONS. logging. logfactory; import COM. defonds. CDs. common. util. commonutil; // HTTP breakpoint resume demo (client test tool: Express Train, thunder) public class arcsynchttpdownloadservlet extends httpservlet {Private Static final long serialversionuid = 1l; Final Static log = logfactory. getlog (arcsynchttpdownloadservlet. class); @ overrideprotected void doget (httpservletrequest req, httpservletresponse resp) throws servletexception, ioexception {This. dopost (req, resp) ;}@ overrideprotected void dopost (httpservletrequest request, httpservletresponse response) {file downloadfile = new file ("D:/defonds/book/pattern/repository "); // The file to be downloaded long filelength = downloadfile. length (); // record the file size long pastlength = 0; // record the downloaded file size int rangeswitch = 0; // 0: Full-text download from the beginning; 1: download from a byte (Bytes = 27000-); 2: Download from a byte to a byte (Bytes = 27000-39000) Long tolength = 0; // record that the client needs to be downloaded The last byte offset of the byte segment (for example, bytes = 27000-39000, the value is 39000) Long contentlength = 0; // string rangebytes = ""; // record the total number of bytes requested by the client. For example, randomaccessfile RAF = NULL in the form of "bytes = 27000-" or "bytes = 27000-39000; // read data outputstream OS = NULL; // write data outputstream out = NULL; // buffer byte B [] = new byte [1024]; // Save the container if (request. getheader ("range ")! = NULL) {// The start byte response of the downloaded file block requested by the client. setstatus (javax. servlet. HTTP. httpservletresponse. SC _partial_content); log.info ("request. getheader (\ "range \") = "+ request. getheader ("range"); rangebytes = request. getheader ("range "). replaceall ("bytes =", ""); If (rangebytes. indexof ('-') = rangebytes. length ()-1) {// bytes = 969998336-rangeswitch = 1; rangebytes = rangebytes. substring (0, rangebytes. indexof ('-'); pastl Ength = long. parselong (rangebytes. trim (); contentlength = filelength-pastlength + 1; // The client requests byte after 969998336} else {// bytes = 1275856879-1275877358rangeswitch = 2; string temp0 = rangebytes. substring (0, rangebytes. indexof ('-'); string temp2 = rangebytes. substring (rangebytes. indexof ('-') + 1, rangebytes. length (); pastlength = long. parselong (temp0.trim (); // bytes = 1275856879-1275877358, from 1,275,856,879th Bytes start to download tolength = long. parselong (temp2); // bytes = 1275856879-1275877358, to the end of the 1,275,877,358th bytes contentlength = tolength-pastlength + 1; // The client requests bytes between 1275856879 and 1275877358} else {// download contentlength = filelength from the beginning; // The client requires full-text download}/*** if Content-Length is set, the client automatically downloads multiple threads. If you do not want to support multithreading, do not set this parameter. * The response format is: * Content-Length: [total file size]-[start byte of the downloaded file block requested by the client] * servletactioncontext. getresponse (). setheader ("Content-Length", * New Long (file. length ()-P ). tostring (); */response. reset (); // tell the client to allow multi‑thread download of resumable data transfer. The response format is accept-ranges: bytesresponse. setheader ("Accept-ranges", "bytes"); // if it is the first time that resumable data transfer has not been performed, the status is 200 by default, and no explicit settings are required; the response format is: HTTP/1.1 200 okif (pastlength! = 0) {// The response format is: // content-range: bytes [start byte of the file block]-[total file size-1]/[total file size] log.info ("---------------------------- not download from the beginning! The server is about to start resumable data transfer... "); Switch (rangeswitch) {Case 1: {// For bytes = 27000-request string contentrange = new stringbuffer (" bytes "). append (New Long (pastlength ). tostring ()). append ("-"). append (New Long (filelength-1 ). tostring ()). append ("/"). append (New Long (filelength ). tostring ()). tostring (); response. setheader ("content-range", contentrange); break;} Case 2: {// string contentrange = rangebyt for bytes = 27000-39000 requests Es + "/" + new long (filelength ). tostring (); response. setheader ("content-range", contentrange); break;} default: {break;} else {// download log.info from the beginning ("-------------------------- download from the beginning! ");} Try {response. addheader ("content-disposition", "attachment; filename = \" "+ downloadfile. getname () + "\" "); response. setcontenttype (commonutil. setcontenttype (downloadfile. getname (); // set the MIME type. response. addheader ("Content-Length", String. valueof (contentlength); OS = response. getoutputstream (); out = new bufferedoutputstream (OS); RAF = new randomaccessfile (downloadfile, "R"); try {s Witch (rangeswitch) {Case 0: {// normal download, or download from the beginning // same as 1} Case 1: {// request for bytes = 27000-Raf. seek (pastlength); // for client requests in the form of bytes = 969998336-, skip the 969998336 bytes int n = 0; while (n = Raf. read (B, 0, 1024 ))! =-1) {out. write (B, 0, n);} break;} Case 2: {// request for bytes = 27000-39000 Raf. seek (pastlength-1); // for client requests in the form of bytes = 1275856879-1275877358, 1,275,856,879th bytes int n = 0; long readlength = 0; // record the number of read bytes while (readlength <= contentlength-1024) {// read most of the bytes here n = Raf. read (B, 0, 1024); readlength + = 1024; out. write (B, 0, n);} If (readlength <= contentlength) {// The remaining less than 1024 bytes are read here n = Raf. read (B, 0, (INT) (contentlength-readlength); out. write (B, 0, n);} // Raf. seek (pastlength); // for client requests in the form of bytes = 1275856879-1275877358, 1,275,856,879th bytes are found. // while (RAF. getfilepointer () <tolength) {// out. write (RAF. read (); //} break;} default: {break;} Out. flush ();} catch (ioexception IE) {/*** when writing data, * exceptions such as clientabortexception are caused by client cancellation, when the server continues to write data to the browser, * this exception is thrown, which is normal. * Especially for client software such as Xunlei, * it is clear that there is already a thread reading bytes = 1275856879-1275877358. * If reading is not completed in a short time, thunder will launch the second and third... The thread is used to read the same byte segment. * Until one thread completes reading, Thunder will kill other threads that are downloading the same byte segment. * The server throws clientabortexception. * Therefore, we ignore this exception * // ignore} catch (exception e) {log. Error (E. getmessage (), e);} finally {If (OUT! = NULL) {try {out. Close ();} catch (ioexception e) {log. Error (E. getmessage (), e) ;}} if (RAF! = NULL) {try {Raf. Close () ;}catch (ioexception e) {log. Error (E. getmessage (), e );}}}}}

Web. xml configuration list of arcsynchttpdownloadservlet:

<! -- HTTP breakpoint resume Demo: 127.0.0.1/CdS/HTTP --> <servlet-Name> httpservlet </servlet-Name> <servlet-class> COM. defonds. CDs. common. arcsynchttpdownloadservlet </servlet-class> </servlet> <servlet-mapping> <servlet-Name> httpservlet </servlet-Name> <URL-pattern>/HTTP </url-Pattern> </servlet-mapping>

The tool class com. defonds. CDs. Common. util. commonutil called by arcsynchttpdownloadservlet source code:

package com.defonds.cds.common.util;public class CommonUtil {public static String setContentType(String returnFileName){String contentType = "application/octet-stream";if (returnFileName.lastIndexOf(".") < 0)return contentType;returnFileName = returnFileName.toLowerCase();returnFileName = returnFileName.substring(returnFileName.lastIndexOf(".")+1);if (returnFileName.equals("html") || returnFileName.equals("htm") || returnFileName.equals("shtml")){contentType = "text/html";} else if (returnFileName.equals("css")){contentType = "text/css";} else if (returnFileName.equals("xml")){contentType = "text/xml";} else if (returnFileName.equals("gif")){contentType = "image/gif";} else if (returnFileName.equals("jpeg") || returnFileName.equals("jpg")){contentType = "image/jpeg";} else if (returnFileName.equals("js")){contentType = "application/x-javascript";} else if (returnFileName.equals("atom")){contentType = "application/atom+xml";} else if (returnFileName.equals("rss")){contentType = "application/rss+xml";} else if (returnFileName.equals("mml")){contentType = "text/mathml"; } else if (returnFileName.equals("txt")){contentType = "text/plain";} else if (returnFileName.equals("jad")){contentType = "text/vnd.sun.j2me.app-descriptor";} else if (returnFileName.equals("wml")){contentType = "text/vnd.wap.wml";} else if (returnFileName.equals("htc")){contentType = "text/x-component";} else if (returnFileName.equals("png")){contentType = "image/png";} else if (returnFileName.equals("tif") || returnFileName.equals("tiff")){contentType = "image/tiff";} else if (returnFileName.equals("wbmp")){contentType = "image/vnd.wap.wbmp";} else if (returnFileName.equals("ico")){contentType = "image/x-icon";} else if (returnFileName.equals("jng")){contentType = "image/x-jng";} else if (returnFileName.equals("bmp")){contentType = "image/x-ms-bmp";} else if (returnFileName.equals("svg")){contentType = "image/svg+xml";} else if (returnFileName.equals("jar") || returnFileName.equals("var") || returnFileName.equals("ear")){contentType = "application/java-archive";} else if (returnFileName.equals("doc")){contentType = "application/msword";} else if (returnFileName.equals("pdf")){contentType = "application/pdf";} else if (returnFileName.equals("rtf")){contentType = "application/rtf";} else if (returnFileName.equals("xls")){contentType = "application/vnd.ms-excel"; } else if (returnFileName.equals("ppt")){contentType = "application/vnd.ms-powerpoint";} else if (returnFileName.equals("7z")){contentType = "application/x-7z-compressed";} else if (returnFileName.equals("rar")){contentType = "application/x-rar-compressed";} else if (returnFileName.equals("swf")){contentType = "application/x-shockwave-flash";} else if (returnFileName.equals("rpm")){contentType = "application/x-redhat-package-manager";} else if (returnFileName.equals("der") || returnFileName.equals("pem") || returnFileName.equals("crt")){contentType = "application/x-x509-ca-cert";} else if (returnFileName.equals("xhtml")){contentType = "application/xhtml+xml";} else if (returnFileName.equals("zip")){contentType = "application/zip";} else if (returnFileName.equals("mid") || returnFileName.equals("midi") || returnFileName.equals("kar")){contentType = "audio/midi";} else if (returnFileName.equals("mp3")){contentType = "audio/mpeg";} else if (returnFileName.equals("ogg")){contentType = "audio/ogg";} else if (returnFileName.equals("m4a")){contentType = "audio/x-m4a";} else if (returnFileName.equals("ra")){contentType = "audio/x-realaudio";} else if (returnFileName.equals("3gpp") || returnFileName.equals("3gp")){contentType = "video/3gpp";} else if (returnFileName.equals("mp4") ){contentType = "video/mp4";} else if (returnFileName.equals("mpeg") || returnFileName.equals("mpg") ){contentType = "video/mpeg";} else if (returnFileName.equals("mov")){contentType = "video/quicktime";} else if (returnFileName.equals("flv")){contentType = "video/x-flv";} else if (returnFileName.equals("m4v")){contentType = "video/x-m4v";} else if (returnFileName.equals("mng")){contentType = "video/x-mng";} else if (returnFileName.equals("asx") || returnFileName.equals("asf")){contentType = "video/x-ms-asf";} else if (returnFileName.equals("wmv")){contentType = "video/x-ms-wmv";} else if (returnFileName.equals("avi")){contentType = "video/x-msvideo";}return contentType;}}

The sample code in this article is used in the client to use flash get 3 and thunder 7 to test OK in the resumable upload environment.

This article is only a demo for technical exchanges. The technical level and knowledge are limited. errors and mistakes are inevitable. Please forgive me. Contact the author for criticism and technical exchange MSN: defonds # hotmail.com (#=@). You can also send me an email, email: defonds # 163.com( #= @).

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.