自己动手写一个java版简单云相册
程序员文章站
2024-03-13 15:26:21
动手写一个java版简单云相册,实现的功能是:
用户可以一次上传一个至多个文件。
用户可以下载其他人上传的图片。
用户可以查看其他所有人的图片。
用户只能删...
动手写一个java版简单云相册,实现的功能是:
用户可以一次上传一个至多个文件。
用户可以下载其他人上传的图片。
用户可以查看其他所有人的图片。
用户只能删除通过自己ip上传的图片。
用到的技术:
文件上传下载、设计模式、dom4j、xpath等。
先看下2个页面:
源代码:
web.xml:
<?xml version="1.0" encoding="utf-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns: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云相册</title> <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>选择文件:</td>"+ "<td> <input type='file' name='file"+t+"'> </td> "+ "<td>文件说明:</td>"+ "<td> <input type='text' name='text"+t+"'> </td> "+ "<td> <input type='button' value='删除文件' 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">相册上传:</font></h1> <form action="/myphoto/upload" method="post" enctype="multipart/form-data"> <table border="1px;double;#ff0000"> <tr> <td>选择文件:</td> <td> <input type="file" name="file1"> </td> <td>文件说明:</td> <td> <input type="text" name="text1"> </td> <td> <input type="button" value="删 除 文 件" onclick="delfile(this)"> </td> </tr> <tr> <td colspan=2> <input type="submit" value="上 传 文 件"> </td> <td colspan=3> <input type="button" value="添 加 文 件" onclick="addfile(this)"> </td> </tr> </table> </form> <form action="/myphoto/cloudphoto" method="post" enctype="multipart/form-data"> <table border="1px;double;#ff0000"> <tr> <td colspan=5><input type="submit" value="进 入 云 相 册" 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 获取uuid */ public static string getuuid(){ return uuid.randomuuid().tostring().replace("-", ""); } /** * @param uuid * @return 通过uuid,获得打散后的路径 */ public static string getdir(string uuid){ string dir1 = integer.tohexstring( uuid.hashcode() & 0xf ); string dir2 = integer.tohexstring( (uuid.hashcode() & 0xf0)>>4 ); return "/"+dir1+"/"+dir2; } //日期时间格式 private static simpledateformat sdf = new simpledateformat("yyyy年mm月dd日 hh:mm:ss"); /** * @return 返回的是上传的时候的日期时间 */ 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{ try { saxreader sax = new saxreader(); //因为我们的资源已经从myelipse中发布到tomcat服务器中了,所以跟原来的纯java项目不一样了。 //利用当前类找到它的类加载器,然后通过该类加载器再去获得资源路径 path = dom4jfactory.class.getclassloader().getresource("photo.xml").getpath(); //getclassloader()返回:加载此对象所表示的类或接口的类加载器 //public url getresource(string name)返回:读取资源的 url 对象;如果找不到该资源,或者调用者没有足够的权限获取该资源,则返回 null。 //此方法首先搜索资源的父类加载器;如果父类加载器为 null,则搜索的路径就是虚拟机的内置类加载器的路径。 //public string getpath()获取此 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 获取相册的document */ public static document getdocument(){ return dom; } /** * 进行photo.xml的保存,保存到本地 */ public static boolean save(){ try { xmlwriter w = new xmlwriter(new fileoutputstream(path)); w.write(dom); w.close(); return true; } catch (unsupportedencodingexception e) { return false; } catch (filenotfoundexception e) { return false; } catch (ioexception e) { return false; } } public static boolean del(string uuid){ node node = dom.selectsinglenode("[@uuid='"+uuid+"']"); if(node==null){ return false; } node.getparent().remove(node); return true; } /** * 测试用 * @param args */ public static void main(string[] args){ system.out.println( getdocument() ); } }
photomodel.java-值对象
package cn.hncu.domain; /** * 值对象封装 * @author 陈浩翔 * 2016-7-24 */ public class photomodel { private string uuid;//uuid private string realname="";//图片真实文件名(上传时的文件名) private string ext;//后缀名 private string dir;//打散后的路径 private string datetime;//上传文件的时间 private string ip;//上传者的ip private string desc;//文件的说明 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 数据的保存 */ public boolean save(photomodel photo); /** * @return 返回所所有的图片信息 */ public list<photomodel> getall(); /** * @param uuid * @return 通过uuid 查找那个被封装的值对象 */ public photomodel getsinglebyuuid(string uuid); /** * @param uuid * @return 通过uuid删除photos.xml中该图片的信息 */ public boolean deletexml(string uuid); /** * @param dir * @return 通过路径删除服务器磁盘中该图片的信息 */ public boolean deletefile(string pathfilename); }
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 = dom4jfactory.getdocument(); element root = dom.getrootelement(); //添加属性 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> list = new arraylist<photomodel>(); document dom = dom4jfactory.getdocument(); element root = dom.getrootelement(); iterator<element> it = root.elementiterator("photo"); //通过dom4j获得photo元素的迭代器,也可以通过xpath来找到所有的 photo //list<node> lists = dom.selectnodes("//photo[@uuid]"); //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; /** * 工厂方法 * @author 陈浩翔 * 2016-7-24 */ public class photodaofactory { public static photoserimpl getphotodao(){ return new photoserimpl(); } }
上传-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 response) throws servletexception, ioexception { response.setcontenttype("text/html;charset=utf-8"); response.getwriter().print("<h1>很抱歉,本页面不支持get方式访问!!!</h1>"); response.getwriter().print("<a href='javascript:history.go(-1)'>返回上一页</a> "); } public void dopost(httpservletrequest request, httpservletresponse response) throws servletexception, ioexception { response.setcontenttype("text/html;charset=utf-8"); final printwriter out = response.getwriter(); //防黑-非multipart表单提交 //使用上传工具的方式 boolean boo = servletfileupload.ismultipartcontent(request); if(!boo){ out.print("<h1>不支持普通表单的提交方式!</h1>"); return; } 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");//设置文件名编码 string path = getservletcontext().getrealpath("/photos"); fileitem fi = null; try { list<fileitem> list = upload.parserequest(request); photomodel photo = new photomodel();//数据封装---需要7个属性 photo.setrealname(""); int cont=0; for(fileitem f:list){ if(cont!=0 && cont%2==0 && !photo.getrealname().equals("")){ photo = new photomodel();//重新数据封装 } fi=f; if(fi.isformfield()){//普通表单组件 //得到文件说明 string desc = fi.getstring("utf-8"); photo.setdesc(desc);//#1 }else{ //防黑3-如果在file组件中不选择文件 if(fi.getsize()==0){ photo.setrealname(""); cont++; continue; } string filename = fi.getname(); filename = filename.substring( filename.lastindexof("\\")+1);//真实文件名 photo.setrealname(filename);//#2 string ext = filename.substring(filename.lastindexof("."));//扩展名 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 //打散目录 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); //存入磁盘-法二:fileutils.copyinputstreamtofile(in, new file(filename2));//※2※ 把图片文件存储到服务器硬盘 photo = new photomodel();//重新数据封装 } } } catch (fileuploadexception e) { e.printstacktrace(); } catch (exception e) { e.printstacktrace(); }finally{ if(fi!=null){ fi.delete(); } if(dom4jfactory.save()){ out.print("<h1>上传成功!</h1>"); out.print("<a href='javascript:history.go(-1)'>返回上一页</a> "); }else{ out.print("<h1>上传失败!</h1>"); out.print("<a href='javascript:history.go(-1)'>返回上一页</a> "); } } } }
显示所有文件-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 response) 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>很抱歉,你没有权限访问!!!</h1>"); } } public void dopost(httpservletrequest request, httpservletresponse response) throws servletexception, ioexception { 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云相册</title></head>"); out.println(" <body>"); out.println("<table border='1px;double;#ff0000'>"); out.println("<tr>"); out.println("<td>文件名</td>"); out.println("<td>上传时间"); out.println("<td>文件</td>"); out.println("<td>文件说明</td>"); out.println("<td>操作</td> "); out.println("</tr>"); string tdwh = "style='width:200px; height:200px;'"; // 显示所有图片 photodao dao = photodaofactory.getphotodao(); list<photomodel> photos = dao.getall(); for (photomodel photo : photos) { string filename = photo.getrealname(); string time = photo.getdatetime(); // 输出图片 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() + "'>删除</a>"; string downstr = "<a href='/myphoto/servlet/downservlet?uuid=" + photo.getuuid() + "'>下载</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(); } }
删除文件-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 { //注入 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, ioexception { 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>你没有权限删除这个文件!!!</h1>"); out.print("<a href='javascript:history.go(-1)'>返回上一页</a> "); return ; } //1.删除数据库中的信息 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)){ //重定向到相册页面 response.sendredirect("/myphoto/cloudphoto?pwd=chx"); }else{ out.print("<h1>无法从服务器中删除,文件正在被占用!!!</h1>"); out.print("<a href='javascript:history.go(-1)'>返回上一页</a> "); } }else{ out.print("<h1>该文件已经不存在!!!</h1>"); out.print("<a href='javascript:history.go(-1)'>返回上一页</a> "); } } } }
下载文件-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, ioexception { string uuid = request.getparameter("uuid"); system.out.println(uuid); photomodel photo = dao.getsinglebyuuid(uuid); system.out.println(photo); if(photo!=null){ //设置响应头--内容接收程序--浏览器看到这个响应头,就会把它认为的下载程序打开 //(如果识别迅雷那么就会自动打开迅雷,如果没有则会打开一个“文件另存为”的对话框) response.setcontenttype("application/force-download"); string realname = photo.getrealname(); string agent = request.getheader("user-agent"); system.out.println(agent); if(agent.indexof("mozilla")!=-1){//火狐浏览器 response.setheader("content-disposition", "attachment;filename="+ new string(realname.getbytes("gb2312"),"iso-8859-1")); }else{ //解决中文乱码问题(只要用下面一句对文件名进行编码就行了) realname = urlencoder.encode(realname, "utf-8");//使用指定的编码机制将字符串转换为 application/x-www-form-urlencoded 格式。 response.setheader("content-disposition", "attachment;filename=\""+realname+"\""); //注意:“cttachment;”不能少,否则浏览器会直接在新窗口中打开 } 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>该文件已经被删除了</h1>"); } } }
演示结果
这个我就不演示啦,图片在前面也有,所有的源码我都给了。有兴趣的可以自己取改进一下咯。
其实这个还能上传其他任意类型文件哦,因为我们没有防护后缀名的,而且我们是用字符流传输,全都不会失真(可以当云盘来处理了~~)!!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。