首页 > 编程 > Java > 正文

自己动手写一个java版简单云相册

2019-11-26 14:01:41
字体:
来源:转载
供稿:网友

动手写一个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>");    }  }}

演示结果

这个我就不演示啦,图片在前面也有,所有的源码我都给了。有兴趣的可以自己取改进一下咯。
其实这个还能上传其他任意类型文件哦,因为我们没有防护后缀名的,而且我们是用字符流传输,全都不会失真(可以当云盘来处理了~~)!!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表