Simple File Upload is to upload the entire file together. In this request, the file is uploaded to the server. For the outdoor job platform, the Network stability is a problem. In addition, the platform's large file nature, therefore, it is more appropriate to use resumable upload in this platform to upload files.
Resumable data transfer: after the client communicates with the server and learns about the size of the transmitted file, it transfers the remaining untransmitted files in parts based on the size of the file block, the server writes these block files to the same file a little bit to form a complete file for resumable data transfer. The client logic is shown as follows:
The file upload and download function of flex uses filereference, and the load method and data attribute are provided after flashplayer10. After filereference executes the load method, data stores the data of the file represented by filereference, which is a bytearray object. That is, we can access the files loaded by flex in bytes, this also provides the possibility of multipart processing for files during resumable upload.
FLEX can communicate with Java to upload files in multiple ways. This article uses Socket Communication to transmit files. The flex code is as follows:
// Use socketsocket = new socket; socket. connect ("12.156.53.29", 1234); // connect to the server // listen for socket connection. addeventlistener (event. connect, function conn () {// send the name socket. writeutf (filereference. name); socket. flush (); // file size socket. writeutf (string (filereference. data. length); socket. flush () ;}); // listen to accept data socket. addeventlistener (progressevent. socket_data, function receivedata () {// uploaded var Len: String = socket. readutf (); If (LEN = "0") {If (filereference. data. length <1024) {socket. writebytes (filereference. data);} else {socket. writebytes (filereference. data,);} socket. flush ();} else {If (filereference. data. length-uint (LEN)> 1024) {socket. writebytes (filereference. data, uint (LEN), 1024);} else {socket. writebytes (filereference. data, uint (LEN), filereference. data. length-uint (LEN);} socket. flush ();}});// Listener connection close socket. addeventlistener (event. Close, functioncloseconn (){});
There is a socket class in the Flash .net package. In the description of this document, we can understand that socket communication requires the use of the socket policy file. In the actual socket communication process, no matter what information we send on the client, the first received information from the socket on the server will be <policy-file-Request/>. This information is in the policy file that requires the server to provide socket communication to the client, in which information such as the communication port number is specified. The Flash Player Security Mechanism is involved in this process. However, we have learned that flex must receive Flash Player policy file requests on port 843 by default for cross-domain socket communication. Note that the request to the policy file and the request initiated during the resumable data transfer process are two independent connections with the socket connection of the server. After the connection is completed, we need to close the connection of the policy file request, so that flash player will automatically reconnect, so as to achieve the socket connection of resumable data transfer, otherwise our active requests will not be connected.
For the content of the above technique, I have done this: I have created two listener listeners, one listening for the request to the policy file, and the other listening for the request to resume the socket connection to the breakpoint, the latter is our master request. Multiple Threads are used for processing each listener. Each time a socket connection request is received, a thread is created to process the policy file request or resumable upload request.
Configure listener in Web. xml
<! -- Listener for uploading large files --> <listener> <display-Name> mylistener </display-Name> <listener-class> COM. fileoperation. largefileuploadlistener </listener-class> </listener> <! -- Security Policy listener for large file upload ports --> <listener> <display-Name> policylistener </display-Name> <listener-class> COM. fileoperation. largefileuploadpolicylistener </listener-class> </listener>
Largefileuploadpolicylistener. Java:
Package COM. fileoperation; import java.net. serversocket; import java.net. socket; import javax. servlet. servletcontextevent; import Org. apache. log4j. logger; public class largefileuploadpolicylistener extends javax. servlet. HTTP. httpservlet implements javax. servlet. servletcontextlistener {Private Static final long serialversionuid = 1l; Private Static final logger log = logger. getlogger (largefileuploadlistene R. Class); Private Static thread = NULL; @ suppresswarnings ("deprecation") Public void contextdestroyed (servletcontextevent arg0) {If (thread! = NULL) {thread = NULL;} public void contextinitialized (servletcontextevent arg0) {try {thread = new thread () {public void run () {log.info ("large file upload Listening Starts .... "); Try {serversocket policyserversocket = new serversocket (integer. parseint ("843"); // server socket policyclientsocket = NULL; socket clientsocket = NULL; while (true) {policyclientsocket = policyserversocket. accept (); // obtain the socket log.info ("the request has been received from the client ..... "); New mypolicyserverthread (policyclientsocket) ;}} catch (exception e) {log. error ("receiving large file exceptions:", e) ;}}; thread. start ();} catch (exception e) {log. error ("Startup listener exception:", e );}}}
Mypolicyserverthread. Java:
Package COM. fileoperation; import Java. io. bufferedreader; import Java. io. ioexception; import Java. io. inputstreamreader; import Java. io. printstream; import Java. io. unsupportedencodingexception; import java.net. socket; import Org. apache. log4j. logger; public class mypolicyserverthread extends thread {Private Static final logger log = logger. getlogger (myserverthread. class); Private Socket socket; private final String policy_xml = "<policy-file-Request/>"; private final string cross_xml = "<? XML version = \ "1.0 \"?> "+" <Cross-domain-Policy> "+" <site-control permitted-Cross-Domain-policies = \ "all \"/> "+" <allow-access- from domain = \ "* \" to-ports = \ "1234 \"/> "+" </Cross-Domain-Policy> \ 0 "; public mypolicyserverthread (Socket socket) {This. socket = socket; this. start () ;}@ overridepublic void run () {try {bufferedreader readerin = new bufferedreader (New inputstreamreader (socket. getinputstream (); printstream printout = new printstream (socket. getoutputstream (); char [] by = new char [22]; readerin. read (by, 0, 22); string S = new string (by); If (S. equals (policy_xml) {system. out. println ("receive policy-file-request authentication"); printout. print (cross_xml); printout. flush (); readerin. close (); printout. close (); socket. close (); system. out. println ("completed policy-file-request authentication") ;}} catch (unsupportedencodingexception e) {e. printstacktrace ();} catch (ioexception e) {e. printstacktrace ();}}}
The above is the processing process of the socket connection of the policy file. This process is initiated by Flash Player by default. on the client side, you only need to process it on the server without manual intervention, in the preceding policy file, we found that it specifies to-ports = \ "1234 \", indicating that the socket port number requested by the socket is 1234, after the socket connection is disabled, the port number of the flashplayer connection is 1234. The following server processing process is associated with our active requests (resumable data transfer). In the above resumable data transfer logic diagram, only the client logic is defined, the logic of the server actually corresponds to it, and the core is Java. io. randomaccessfile batch writes files to corresponding files. The thread execution in the following code communicates with the socket at the flex end to implement the resumable upload and file upload function.
Largefileuploadlistener. Java
Package COM. fileoperation; import java.net. serversocket; import java.net. socket; import javax. servlet. servletcontextevent; import Org. apache. log4j. logger; public class largefileuploadlistener extends javax. servlet. HTTP. httpservlet implements javax. servlet. servletcontextlistener {Private Static final long serialversionuid = 1l; Private Static final logger log = logger. getlogger (largefileuploadlistener. CIA SS); Private Static thread = NULL; @ suppresswarnings ("deprecation") Public void contextdestroyed (servletcontextevent arg0) {If (thread! = NULL) {thread = NULL;} public void contextinitialized (servletcontextevent arg0) {try {thread = new thread () {public void run () {log.info ("large file upload Listening Starts .... "); Try {serversocket = new serversocket (integer. parseint ("1234"); // server socket clientsocket = NULL; while (true) {clientsocket = serversocket. accept (); // obtain the socket log.info ("the request has been received from the client ..... "); New myserverthread (clientsocket) ;}} catch (exception e) {log. error ("receiving large file exceptions:", e) ;}}; thread. start ();} catch (exception e) {log. error ("Startup listener exception:", e );}}}
Myserverthread. Java:
Package COM. IBM. rise. workplace. fileoperation; import Java. io. datainputstream; import Java. io. dataoutputstream; import Java. io. file; import Java. io. fileinputstream; import Java. io. ioexception; import Java. io. inputstream; import Java. io. randomaccessfile; import java.net. socket; import Java. NIO. channels. filechannel; import Java. NIO. channels. filelock; import Java. util. map; import Java. util. stringtokenizer; import o RG. apache. log4j. logger; public class myserverthread extends thread {Private Static final logger log = logger. getlogger (myserverthread. class); Private Socket socket; Public myserverthread (Socket socket) {This. socket = socket; this. start () ;}@ overridepublic void run () {datainputstream = NULL; dataoutputstream = NULL; randomaccessfile = NULL; Boolean isinfosu Bmission = false; document docinfosubmission = NULL; double totalsize = 0.0; docproperty = NULL; try {datainputstream = new datainputstream (socket. getinputstream (); dataoutputstream = new dataoutputstream (socket. getoutputstream (); // read name string filename = datainputstream. readutf (); string filesize = datainputstream. readutf (); // check whether the uploaded file contains string filepath = "file path"; // you can use the configuration file to clearly write the path to St Ringtokenizer ST = new stringtokenizer (filepath. tostring (), "/"); string toaddpath = ST. nexttoken () + "/"; string totestpath = toaddpath; while (St. hasmoretokens () {toaddpath = ST. nexttoken () + "/"; totestpath + = toaddpath; file inbox = new file (totestpath); If (! Inbox. exists () {inbox. mkdir () ;}/// check the upload location file = new file (filepath + "/" + filename); long position = 0; If (file. exists () {position = file. length ();} // notifies the client that the size of dataoutputstream has been passed. writeutf (string. valueof (position); dataoutputstream. flush (); byte [] buffer = NULL; int READ = 0; while (true) {// detect the upload location file = new file (filepath + "/" + filename ); position = 0; If (file. exists () {position = f Ile. length () ;}// RW indicates the write stream (random read/write) randomaccessfile = new randomaccessfile (file, "RW"); filelock = NULL; filechannel = NULL; filechannel = randomaccessfile. getchannel (); filelock = filechannel. trylock (); // get the file lock and write data if (filelock! = NULL) {randomaccessfile. seek (position); read = 0; buffer = new byte [1024]; read = datainputstream. read (buffer); randomaccessfile. write (buffer, 0, read); If (filelock! = NULL) {filelock. Release (); filelock = NULL;} If (randomaccessfile! = NULL) {randomaccessfile. close (); randomaccessfile = NULL ;}// check the uploaded size file = new file (filepath + "/" + filename); position = 0; If (file. exists () {position = file. length ();} system. out. println ("file" + filename + "transmitted" + String. valueof (position) + "Byte"); // determines whether the file has been transferred. If (position> = long. parselong (filesize) {// file transfer completed system. out. println ("file" + filename + "transferred, total size:" + String. valueof (position) + "Byte"); break;} else {// notify the client that the data size has been transferred to dataoutputstream. writeutf (string. valueof (position); dataoutputstream. flush () ;}// end while // jumps out of the while loop, that is, the file upload has been completed, and the socket communication datainputstream is terminated. close (); dataoutputstream. close (); socket. close ();} catch (ioexception e) {// todo auto-generated catch blocke. printstacktrace ();}}}
Flex uses Socket Communication and does not need to configure related services like accessing Java services through remoteobject, you only need to specify the IP address and port for socket connection in the Flex-side mxml or as file for communication, however, you must handle the policy files required by Flash Player. In addition, the core of resumable upload is to transfer the entire file in one request to multiple requests in multiple parts, and the server can use the relevant classes to integrate the parts.