Write a Java version of a simple cloud album, the implementation of the functions are:
users can upload one to multiple files at a time.
Users can download pictures uploaded by other people.
Users can view pictures of everyone else.
Users can only delete images uploaded via their own IP.
Technology to use:
file upload Download, design mode, dom4j, XPath, etc.
First look at the next 2 pages:
Source:
Xml:
<?xml version= "1.0" encoding= "UTF-8"?> <web-app version= "3.0" xmlns= "Http://java.sun.com/xml/ns/javaee" XM Lns:xsi= "Http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation= "Http://java.sun.com/xml/ns/javaee http:/ /java.sun.com/xml/ns/javaee/web-app_3_0.xsd "> <display-name></display-name> <servlet> < Servlet-name>uploadservlet</servlet-name> <servlet-class>cn.hncu.servlets.uploadservlet</ servlet-class> </servlet> <servlet> <servlet-name>cloudPhotoServlet</servlet-name> < Servlet-class>cn.hncu.servlets.cloudphotoservlet</servlet-class> </servlet> <servlet> < Servlet-name>downservlet</servlet-name> <servlet-class>cn.hncu.servlets.downservlet</ servlet-class> </servlet> <servlet> <servlet-name>DelServlet</servlet-name> < Servlet-class>cn.hncu.servlets.delservlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>UploadServlet</servlet-name> <url-pattern>/upload</ url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>cloudphotoservlet</ servlet-name> <url-pattern>/cloudPhoto</url-pattern> </servlet-mapping> <servlet-mapping > <servlet-name>DownServlet</servlet-name> <url-pattern>/servlet/downservlet</ url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>delservlet</servlet-name > <url-pattern>/servlet/DelServlet</url-pattern> </servlet-mapping> <welcome-file-list
> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
Index.jsp:
<%@ page language= "java" import= "java.util.*" pageencoding= "UTF-8"%> <! DOCTYPE HTML PUBLIC "-//w3c//dtd HTML 4.01 transitional//en" > <html> <head> <title>chx Cloud album </titl e> <script type= "Text/javascript" > Function delfile (input) {table = Input.parentElement.parentElement
. Parentelement;//table.nodename tbody Table.removechild (input.parentElement.parentElement);
} var t=1;
function AddFile (input) {tr = input.parentElement.parentElement;
alert (tr.nodename);
var str = "<td> Select File:</td>" + "<td> <input type= ' file ' name= ' file ' +t+ ' ' > </td> ' + "<td> File Description:</td>" + "<td> <input type= ' text ' name= ' text" +t+ "' > </td> ' +" &
lt;td> <input type= ' button ' value= ' delete file ' onclick= ' Delfile (this) ' > </td> ';
Tr.insertadjacenthtml ("Beforebegin", str); } function Move () {window.location.href= "/myphoto/cLoudphoto ";
} </script> <style type= "Text/css" > #font {color:red; } </style> </head> <body> <h1><font id= "Font" > album Upload:</font></h1> <fo RM action= "/myphoto/upload" method= "post" enctype= "Multipart/form-data" > <table border= "1px;double; #ff0000" > <tr> <td> Select File:</td> <td> <input type= "file" name= "File1" > </td > <td> File Description:</td> <td> <input type= "text" name= "Text1" > </td> &L t;td> <input type= "button" value= "Delete file" onclick= "Delfile (This)" > </td> </tr> <tr>
; <TD colspan=2> <input type= "Submit" value= "Upload file" > </td> <td colspan=3> <input "Type=" Button "value=" Add File "onclick=" AddFile (this) > </td> </tr> </table> </form> ; form action= "/myphoto/cloudphoto" MethoD= "POST" enctype= "Multipart/form-data" > <table border= "1px;double; #ff0000" > <tr> <td C
Olspan=5><input type= "Submit" value= "into the Cloud album" onclick= "Move ()" ></td> </tr> </table>
</form> </body> </html>
Photo.xml:
<?xml version= "1.0" encoding= "UTF-8"?>
<photos>
</photos>
Myutils.java:
Package cn.hncu.utils;
Import Java.text.SimpleDateFormat;
Import java.util.Date;
Import Java.util.UUID;
public class Myutils {
/**
* @return get UUID
/public static String Getuuid () {
return Uuid.randomuuid (). toString (). Replace ("-", "");
/**
* @param uuid
* @return through the UUID, get the beaten path
/public static string Getdir (String uuid) {
String Dir1 = integer.tohexstring (Uuid.hashcode () & 0xf);
String Dir2 = integer.tohexstring (Uuid.hashcode () & 0xf0) >>4);
Return "/" +dir1+ "/" +DIR2;
}
Date time format
private static SimpleDateFormat SDF = new SimpleDateFormat ("yyyy mm month DD Day HH:mm:ss");
/**
* @return Returns the date time of the upload/public
static String GetCurrentDateTime () {return
Sdf.format (new Date ());
}
Dom4jfactory.java:
Package cn.hncu.utils;
Import Java.io.FileInputStream;
Import java.io.FileNotFoundException;
Import Java.io.FileOutputStream;
Import java.io.IOException;
Import java.io.UnsupportedEncodingException;
Import org.dom4j.Document;
Import org.dom4j.DocumentException;
Import org.dom4j.Element;
Import Org.dom4j.Node;
Import Org.dom4j.io.SAXReader;
Import Org.dom4j.io.XMLWriter;
public class Dom4jfactory {private static Document dom=null;
private static String path; Static block! It will only run once!
The feature is to execute static{try {saxreader sax = new Saxreader () when the class loads;
Because our resources have been released from Myelipse to the Tomcat server, they are not the same as the original pure Java projects.
Use the current class to find its ClassLoader, and then get the resource path Path = Dom4jFactory.class.getClassLoader (). GetResource ("Photo.xml"). GetPath (); getClassLoader () returns: the class loader//public URL getresource (String name) that loads the class or interface represented by this object returns: The URL object that reads the resource, or if the resource is not found, or if the caller does not have enough
Permission to obtain the resource, NULL is returned.
This method first searches for the parent class loader of the resource, or if the parent class loader is null, the path of the search is the path of the virtual machine's built-in ClassLoader.
The public String GetPath () Gets the path portion of this URL. SYSTEM.OUT.PRINTLN (path);
Dom = Sax.read (new FileInputStream (path));
catch (FileNotFoundException e) {throw new RuntimeException (e);
catch (Documentexception e) {throw new RuntimeException (e);
/** * @return Obtain the Document/public static document GetDocument () {return Dom of the album; /** * For Photo.xml Save, save to Local/public static Boolean save () {try {XMLWriter w = new XMLWriter (New F
Ileoutputstream (path));
W.write (DOM);
W.close ();
return true;
catch (Unsupportedencodingexception e) {return false;
catch (FileNotFoundException e) {return false;
catch (IOException e) {return false;
The public static Boolean del (String uuid) {node node = Dom.selectsinglenode ("[@uuid = ' +uuid+ ']");
if (Node==null) {return false;
} node.getparent (). Remove (node);
return true; /** * Test with * @param args/public static void main (String[] args) {System.out.println (GetDocument ());
}
}
Photomodel.java-Value Object
Package cn.hncu.domain; /** * Value Object encapsulation * @author Chen Haoxiang * 2016-7-24/public class Photomodel {private string Uuid;//uuid private string Real
Name= ""//Picture Real file name (filename uploaded) private string ext;//suffix private string dir;//the path private string datetime;//the time when the file was uploaded
private string ip;//The description of the IP private string desc;//file for the upload public string Getuuid () {return UUID;
public void Setuuid (String uuid) {this.uuid = UUID;
Public String Getrealname () {return realname;
} public void Setrealname (String realname) {this.realname = Realname;
Public String Getext () {return ext;
public void Setext (String ext) {this.ext = ext;
Public String Getdir () {return dir;
public void Setdir (String dir) {this.dir = dir;
Public String GetDateTime () {return dateTime;
public void SetDateTime (String dateTime) {this.datetime = datetime;
Public String GetIP () {return IP;
} public void SetIp (String IP) { This.ip = IP;
Public String GetDesc () {return desc;
} public void Setdesc (String desc) {THIS.DESC = desc;
@Override public String toString () {return "Photomodel [uuid= + uuid +", realname= "+ Realname +", ext= "
+ ext + ", dir=" + dir + ", datetime=" + DateTime + ", ip=" + IP + ", desc=" + desc + "];
}
}
Photodao.java:
Package Cn.hncu.photoDao.Dao;
Import java.util.List;
Import Cn.hncu.domain.PhotoModel;
Public interface Photodao {
/**
* @param photo
* @return Data Save
/Public
Boolean Save (Photomodel photo);
/**
* @return return all picture information/public
list<photomodel> getAll ();
/**
* @param uuid
* @return to find the encapsulated value object
/Public Photomodel getsinglebyuuid (String uuid) through a UUID; c18/>/**
* @param uuid
* @return Remove information from the picture in Photos.xml via UUID
/public boolean deletexml (String UUID);
/**
* @param dir
* @return removes the information from the picture on the server disk by path
/public boolean deletefile (String pathfilename); c28/>}
Photoserimpl.java:
Package Cn.hncu.photoDao.impl;
Import Java.io.File;
Import java.util.ArrayList;
Import Java.util.Iterator;
Import java.util.List;
Import org.dom4j.Document;
Import org.dom4j.Element;
Import Org.dom4j.Node;
Import Cn.hncu.domain.PhotoModel;
Import Cn.hncu.photoDao.Dao.PhotoDao;
Import Cn.hncu.utils.Dom4jFactory; public class Photoserimpl implements photodao{@Override public boolean Save (Photomodel photo) {Document dom = D
Om4jfactory.getdocument ();
Element root = Dom.getrootelement ();
Add attribute Element p = root.addelement ("photo");
P.addattribute ("UUID", Photo.getuuid ());
P.addattribute ("Realname", Photo.getrealname ());
P.addattribute ("DateTime", Photo.getdatetime ());
P.addattribute ("IP", Photo.getip ());
P.addattribute ("ext", Photo.getext ());
P.addattribute ("dir", Photo.getdir ());
P.addattribute ("desc", Photo.getdesc ());
return Dom4jfactory.save (); @Override public list<photomodel> GetAll () {list<photomodel&Gt
List = new arraylist<photomodel> ();
Document dom = Dom4jfactory.getdocument ();
Element root = Dom.getrootelement ();
Iterator<element> it = root.elementiterator ("photo");
The iterator of photo elements is obtained by dom4j, and all photo//list<node> lists = Dom.selectnodes ("//photo[@uuid]" can also be found through XPath;
Iterator<node> it = Lists.iterator ();
while (It.hasnext ()) {Element E = It.next ();
Photomodel photo = new Photomodel ();
Photo.setuuid (E.attributevalue ("uuid"));
Photo.setrealname (E.attributevalue ("Realname"));
Photo.setdatetime (E.attributevalue ("DateTime"));
Photo.setext (E.attributevalue ("ext"));
Photo.setip (e.attributevalue ("IP"));
Photo.setdir (E.attributevalue ("dir"));
Photo.setdesc (E.attributevalue ("desc"));
List.add (photo);
} return list;
@Override public Photomodel getsinglebyuuid (String uuid) {list<photomodel> photos=getall (); for (Photomodel photo:photos) {if PHoto.getuuid (). Equals (UUID)) {return photo;
} return null;
@Override public boolean deletexml (String uuid) {Document dom = dom4jfactory.getdocument ();
Element e = (Element) Dom.selectsinglenode ("//photo[@uuid = '" +uuid.trim () + "']");
Return E.getparent (). Remove (e);
@Override public boolean DeleteFile (String pathfilename) {try {File file = new file (pathfilename);
if (file.exists ()) {file.delete ();
return true;
catch (Exception e) {return false;
}
}
}
Photodaofactory.java:
Package cn.hncu.photoDao.factory;
Import Cn.hncu.photoDao.impl.PhotoSerImpl;
/**
* Factory Method
* @author Chen Haoxiang
* 2016-7-24/public
class Photodaofactory {public
static Photoserimpl Getphotodao () {return
new Photoserimpl ();
}
}
Upload-uploadservlet.java:
Package cn.hncu.servlets;
Import Java.io.File;
Import java.io.IOException;
Import Java.io.PrintWriter;
Import java.util.List;
Import javax.servlet.ServletException;
Import Javax.servlet.http.HttpServlet;
Import Javax.servlet.http.HttpServletRequest;
Import Javax.servlet.http.HttpServletResponse;
Import Org.apache.commons.fileupload.FileItem;
Import org.apache.commons.fileupload.FileUploadException;
Import Org.apache.commons.fileupload.disk.DiskFileItemFactory;
Import Org.apache.commons.fileupload.servlet.ServletFileUpload;
Import Cn.hncu.domain.PhotoModel;
Import Cn.hncu.photoDao.Dao.PhotoDao;
Import Cn.hncu.photoDao.factory.PhotoDaoFactory;
Import Cn.hncu.utils.Dom4jFactory;
Import Cn.hncu.utils.MyUtils; public class Uploadservlet extends HttpServlet {public void doget (HttpServletRequest request, HttpServletResponse Respo
NSE) throws Servletexception, IOException {response.setcontenttype ("text/html;charset=utf-8"); Response.getwriter (). Print ("<h1> Sorry, this page is not strongAccess!!! with Get mode
</h1> ");
Response.getwriter (). Print ("<a href= ' Javascript:history.go ( -1) ' > Return prev </a>"); public void DoPost (HttpServletRequest request, httpservletresponse response) throws Servletexception, Ioexceptio
n {response.setcontenttype ("text/html;charset=utf-8");
Final PrintWriter out = Response.getwriter ();
Anti-black-non-multipart form submission//Use Upload tool in the way of Boolean boo = servletfileupload.ismultipartcontent (request); if (!boo) {out.print ("<h1> does not support the presentation of normal forms!")
</h1> ");
Return
The file File = new file ("D:/photocache");
if (!file.exists ()) {File.mkdir ();
} diskfileitemfactory fifactory = new Diskfileitemfactory (1024*10,file);
Servletfileupload upload = new Servletfileupload (fifactory);
Upload.setheaderencoding ("Utf-8");/set file name encoding String path = Getservletcontext (). Getrealpath ("/photos");
Fileitem fi = null;
try {list<fileitem> List = upload.parserequest (request); Photomodel photo = new Photomodel ()//Data encapsulation---requires 7 attributes Photo.setrealname ("");
int cont=0; for (Fileitem f:list) {if (cont!=0 && cont%2==0 &&!photo.getrealname (). Equals (")) {photo
= new Photomodel ();//re-data encapsulation} fi=f;
if (Fi.isformfield ()) {//Common form component//Get file description String desc = fi.getstring ("Utf-8"); PHOTO.SETDESC (DESC)//#1}else{//Anti-Black 3-If the file is not selected in the Files component if (Fi.getsize () ==0) {photo.
Setrealname ("");
cont++;
Continue
String fileName = Fi.getname ();
filename = filename.substring (filename.lastindexof ("\") +1);//real filename photo.setrealname (filename);/#2 String ext = filename.substring (Filename.lastindexof (".")); /extension Photo.setext (EXT);//#3 Photo.setdatetime (Myutils.getcurrentdatetime ());//#4 Photo.setip (Request.getremoteaddr ());//#5 String uuid = Myutils.getuuid (); Photo.setuuid (UUID);//#6 Photo.setdir (Myutils.getdir (UUID))//#7//Scatter directory File Dfile = new
File (Path+photo.getdir ());
if (!dfile.exists ()) {dfile.mkdirs ();
Fi.write (New File (Path+photo.getdir () + "/" +photo.getuuid () +photo.getext ());
} cont++;
if (cont%2==0 &&!photo.getrealname (). Equals ("")) {Photodao DAO = Photodaofactory.getphotodao ();
Boo = Dao.save (photo); Save disk-Law II: Fileutils.copyinputstreamtofile (in, new file (fileName2)),//※2※ store picture file to server hard disk photo = new Photomodel ();
Re-Data Encapsulation}} catch (Fileuploadexception e) {e.printstacktrace ();
catch (Exception e) {e.printstacktrace ();
}finally{if (fi!=null) {fi.delete (); } if (Dom4jfactory.save ()) {out.print ("<h1> upload success!")
</h1> "); Out.print ("<a href=" Javascript:history.go (-1)' > Return to previous Page </a> '); }else{out.print ("<h1> upload failed!")
</h1> ");
Out.print ("<a href= ' Javascript:history.go ( -1) ' > Return prev </a>");
}
}
}
}
Show All Files-cloudphotoservlet.java
Package cn.hncu.servlets;
Import java.io.IOException;
Import Java.io.PrintWriter;
Import java.util.List;
Import javax.servlet.ServletException;
Import Javax.servlet.http.HttpServlet;
Import Javax.servlet.http.HttpServletRequest;
Import Javax.servlet.http.HttpServletResponse;
Import Cn.hncu.domain.PhotoModel;
Import Cn.hncu.photoDao.Dao.PhotoDao;
Import Cn.hncu.photoDao.factory.PhotoDaoFactory; public class Cloudphotoservlet extends HttpServlet {public void doget (HttpServletRequest request, HttpServletResponse R
Esponse) throws Servletexception, IOException {string pwd = (string) request.getparameter ("pwd");
if ("Chx". Equals (pwd)) {doPost (request, response);
else {response.setcontenttype ("text/html;charset=utf-8"); Response.getwriter (). Print ("<h1> Sorry, you do not have access to!!!
</h1> "); } public void DoPost (HttpServletRequest request, httpservletresponse response) throws Servletexception, Ioexc eption {Response.setcontenttyPE ("Text/html;charset=utf-8");
PrintWriter out = Response.getwriter (); Out.println ("<!
DOCTYPE HTML public \-//w3c//dtd HTML 4.01 transitional//en\ ">");
Out.println ("<HTML>");
Out.println ("<head><title>chx Cloud album </TITLE></HEAD>");
Out.println ("<BODY>");
Out.println ("<table border= ' 1px;double; #ff0000 ' >");
Out.println ("<tr>");
OUT.PRINTLN ("<td> filename </td>");
Out.println ("<td> upload Time");
Out.println ("<td> documents </td>");
OUT.PRINTLN ("<td> Document Description </td>");
Out.println ("<td> operation </td>");
Out.println ("</tr>"); String TDWH = "style= ' width:200px";
height:200px; ' ";
Show all pictures Photodao dao = Photodaofactory.getphotodao ();
List<photomodel> photos = Dao.getall ();
for (Photomodel photo:photos) {String fileName = Photo.getrealname ();
String time = Photo.getdatetime (); Output picture String path = Request.getconTextpath () + "/photos/" + photo.getdir () + "/" + photo.getuuid () + Photo.getext ();
SYSTEM.OUT.PRINTLN (path); /myphoto/photos//7/c/a1237a48a6aa451cb22fa78b15bafcea.jpg String img = "<a href=" "+ Path +" ' ><img src=
' "+ Path +" '/></a> ";
String desc = Photo.getdesc ();
String delstr = "<a href= '/myphoto/servlet/delservlet?uuid=" + photo.getuuid () + "' > Delete </a>";
String downstr = "<a href= '/myphoto/servlet/downservlet?uuid=" + photo.getuuid () + "' > Download </a>";
Out.println ("<tr>");
Out.println ("<TD" + TDWH + ">" + fileName + "</td>");
Out.println ("<TD" + TDWH + ">" + Time + "</td>");
Out.println ("<TD" + TDWH + ">" + img + "</td>");
Out.println ("<TD" + TDWH + ">" + desc + "</td>");
Out.println ("<TD" + TDWH + ">" + delstr + " " + downstr + "</td>"); Out.priNtln ("</tr>");
} out.println ("<tr>");
Out.println ("</tr>");
Out.println ("</table>");
Out.println ("</BODY>");
Out.println ("</HTML>");
Out.flush ();
Out.close ();
}
}
Delete file-delservlet.java
Package cn.hncu.servlets;
Import java.io.IOException;
Import Java.io.PrintWriter;
Import javax.servlet.ServletException;
Import Javax.servlet.http.HttpServlet;
Import Javax.servlet.http.HttpServletRequest;
Import Javax.servlet.http.HttpServletResponse;
Import Cn.hncu.domain.PhotoModel;
Import Cn.hncu.photoDao.Dao.PhotoDao;
Import Cn.hncu.photoDao.factory.PhotoDaoFactory;
public class Delservlet extends HttpServlet {//inject private Photodao DAO = Photodaofactory.getphotodao ();
public void doget (HttpServletRequest request, httpservletresponse response) throws Servletexception, IOException {
DoPost (request, response); public void DoPost (HttpServletRequest request, httpservletresponse response) throws Servletexception, ioexcept
ion {String uuid = Request.getparameter ("uuid");
String IP = request.getremoteaddr ();
Response.setcontenttype ("Text/html;charset=utf-8");
PrintWriter out = Response.getwriter (); Photomodel photo = Dao.getsingleByuuid (UUID); if (photo!=null) {if (!photo.getip (). Equals (IP)) {out.print ("<h1> You do not have permission to delete this file!!!
</h1> ");
Out.print ("<a href= ' Javascript:history.go ( -1) ' > Return prev </a>");
return;
//1. Delete information from a database Boolean boo = Dao.deletexml (UUID);
if (boo) {String fileName = "photos/" +photo.getdir () + "/" +photo.getuuid () +photo.getext ();
String pathfilename = Getservletcontext (). Getrealpath (FileName);
if (Dao.deletefile (pathfilename)) {//Redirect to album page Response.sendredirect ("/myphoto/cloudphoto?pwd=chx"); }else{out.print ("<h1> cannot be removed from the server, the file is being occupied!!!
</h1> ");
Out.print ("<a href= ' Javascript:history.go ( -1) ' > Return prev </a>"); }else{Out.print ("<h1> the file no longer exists!!!
</h1> ");
Out.print ("<a href= ' Javascript:history.go ( -1) ' > Return prev </a>");
}
}
}
}
Download file-downservlet.java
Package cn.hncu.servlets;
Import Java.io.FileInputStream;
Import java.io.IOException;
Import Java.io.InputStream;
Import Java.io.OutputStream;
Import Java.net.URLEncoder;
Import javax.servlet.ServletException;
Import Javax.servlet.http.HttpServlet;
Import Javax.servlet.http.HttpServletRequest;
Import Javax.servlet.http.HttpServletResponse;
Import Cn.hncu.domain.PhotoModel;
Import Cn.hncu.photoDao.Dao.PhotoDao;
Import Cn.hncu.photoDao.factory.PhotoDaoFactory;
public class Downservlet extends HttpServlet {private Photodao DAO = Photodaofactory.getphotodao ();
public void doget (HttpServletRequest request, httpservletresponse response) throws Servletexception, IOException {
DoPost (request, response); public void DoPost (HttpServletRequest request, httpservletresponse response) throws Servletexception, Ioexcepti
on {String uuid = Request.getparameter ("uuid");
SYSTEM.OUT.PRINTLN (UUID);
Photomodel photo = Dao.getsinglebyuuid (UUID); System.out.pRINTLN (photo); if (photo!=null) {//Set response header--content receiver--the browser sees this response header, it will be the download program to open//(if the identification of thunder then will automatically open the Thunder, if not, you will open a "File Save as" dialog box) re
Sponse.setcontenttype ("Application/force-download");
String realname = Photo.getrealname ();
String Agent = Request.getheader ("user-agent");
SYSTEM.OUT.PRINTLN (agent); if (Agent.indexof ("Mozilla")!=-1) {//Firefox browser response.setheader ("Content-disposition", "attachment;filename=" + new STR
ING (realname.getbytes ("GB2312"), "iso-8859-1")); }else{//Solve Chinese garbled problem (just use the following sentence to encode the file name) Realname = Urlencoder.encode (realname, "utf-8");//convert string to a using the specified encoding mechanism
pplication/x-www-form-urlencoded format.
Response.setheader ("Content-disposition", "attachment;filename=\", "+realname+"); Note: "Cttachment;"
cannot be less, otherwise the browser will open directly in a new window} String fileName = "photos/" + photo.getdir () + "/" +photo.getuuid () +photo.getext ();
String pathfilename = Getservletcontext (). Getrealpath (FileName); InputStream in = new FileInputStream (Pathfilename);
OutputStream out = Response.getoutputstream ();
byte buf[] = new byte[2048];
int len=0;
while ((Len=in.read (BUF))!=-1) {out.write (buf, 0, Len);
} out.close ();
In.close ();
}else{Response.setcontenttype ("Text/html;charset=utf-8");
Response.getwriter (). println ("<h1> the file has been deleted </h1>");
}
}
}
Demo results
This I will not demonstrate, the picture in front also has, all the source code I have given. Interested in the can make their own improvement slightly.
In fact, this can upload any other type of file Oh, because we do not have a protection suffix name, and we are using the character stream transmission, all will not be distorted (can be treated as a cloud disk ~ ~)!!
The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.