动手写一个java版简单云相册,实现的功能是:
用户可以一次上传一个至多个文件。
用户可以下载其他人上传的图片。
用户可以查看其他所有人的图片。
用户只能删除通过自己IP上传的图片。
用到的技术:
文件上传下载、设计模式、Dom4j、xPath等。
先看下2个页面:
源代码:
web.xml:
UploadServlet cn.hncu.servlets.UploadServlet cloudPhotoServlet cn.hncu.servlets.cloudPhotoServlet DownServlet cn.hncu.servlets.DownServlet DelServlet cn.hncu.servlets.DelServlet UploadServlet /upload cloudPhotoServlet /cloudPhoto DownServlet /servlet/DownServlet DelServlet /servlet/DelServlet index.jsp
index.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>chx云相册 #font{ color:red; } 相册上传:
photo.xml:
MyUtils.java:
package cn.hncu.utils;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
public class MyUtils {
public static String getUUID(){
return UUID.randomUUID().toString().replace("-", "");
}
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");
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);
}
}
public static document getdocument(){
return dom;
}
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;
}
public static void main(String[] args){
System.out.println( getdocument() );
}
}
PhotoModel.java-值对象
package cn.hncu.domain;
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 {
public boolean save(PhotoModel photo);
public List getAll();
public PhotoModel getSingleByUuid(String uuid);
public boolean deleteXml(String uuid);
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 getAll() {
List list = new ArrayList();
document dom = Dom4jFactory.getdocument();
Element root = dom.getRootElement();
Iterator it = root.elementIterator("photo");
//通过DOM4J获得photo元素的迭代器,也可以通过xPath来找到所有的 photo
//List lists = dom.selectNodes("//photo[@uuid]");
//Iterator 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 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;
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("很抱歉,本页面不支持GET方式访问!!!");
response.getWriter().print("返回上一页 ");
}
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("不支持普通表单的提交方式!");
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 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("上传成功!");
out.print("返回上一页 ");
}else{
out.print("上传失败!");
out.print("返回上一页 ");
}
}
}
}
显示所有文件-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("很抱歉,你没有权限访问!!!");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.println("");
out.println("");
out.println(" CHX云相册 ");
out.println(" ");
out.println("| 文件名 | "); out.println("上传时间"); out.println(" | 文件 | "); out.println("文件说明 | "); out.println("操作 | "); out.println("
| " + fileName + " | "); out.println("" + time + " | "); out.println("" + img + " | "); out.println("" + desc + " | "); out.println("" + delStr + " " + downStr + " | "); out.println("
删除文件-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("你没有权限删除这个文件!!!");
out.print("返回上一页 ");
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("无法从服务器中删除,文件正在被占用!!!");
out.print("返回上一页 ");
}
}else{
out.print("该文件已经不存在!!!");
out.print("返回上一页 ");
}
}
}
}
下载文件-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("该文件已经被删除了");
}
}
}
演示结果
这个我就不演示啦,图片在前面也有,所有的源码我都给了。有兴趣的可以自己取改进一下咯。
其实这个还能上传其他任意类型文件哦,因为我们没有防护后缀名的,而且我们是用字符流传输,全都不会失真(可以当云盘来处理了~~)!!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持考高分网。



