设计思路:
用一个值对象封装一个photo信息。
photo值对象包括
private String id;// uuid
private String realName;// 相片真实文件名(上传时的文件名)
private String ext;// 扩展名
private String dir;// 打散后的路径
private String dateTime;
private String ip;
private String desc;// 相片说明
用xml做数据存储,采用dom4j来读写数据。
采用目录打散的方式在服务器中存储图片,因为一个文件夹下面文件数目超过1000性能会下降。
图片点击放大就是用一个<a>
标签来封装<img>
标签。在a标签的href的属性给图片路径即可。
文件上传,采用Apache公司的工具来做,在上一篇博文中提到。
文件下载,设置两个响应头,然后用io读写。注意文件名带中文的。
实现代码如下:
photos.xml
<?xml version="1.0" encoding="UTF-8"?>
<photos></photos>
PhotoModel
package cn.hncu.domain;
public class PhotoModel {
private String id;// uuid
private String realName;// 相片真实文件名(上传时的文件名)
private String ext;// 扩展名
private String dir;// 打散后的路径
private String dateTime;
private String ip;
private String desc;// 相片说明
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
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 [id=" + id + ", realName=" + realName + ", ext="
+ ext + ", dir=" + dir + ", dateTime=" + dateTime + ", ip="
+ ip + ", desc=" + desc + "]";
}
}
PhotoDao
package cn.hncu.photoDao;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Element;
import cn.hncu.domain.PhotoModel;
import cn.hncu.utils.Dom4jFactory;
public class PhotoDao {
public boolean save(PhotoModel photo) {
Document dom = Dom4jFactory.getDom();
Element root = dom.getRootElement();
Element pe = root.addElement("photo");
pe.addAttribute("id", photo.getId());
pe.addAttribute("realName", photo.getRealName());
pe.addAttribute("dateTime", photo.getDateTime());
pe.addAttribute("ip", photo.getIp());
pe.addAttribute("ext", photo.getExt());
pe.addAttribute("dir", photo.getDir());
pe.addElement("desc").setText(photo.getDesc());
boolean boo = Dom4jFactory.save();
return boo;
}
public List<PhotoModel> getAll() {
List<PhotoModel> list = new ArrayList<PhotoModel>();
Document dom = Dom4jFactory.getDom();
Element root = dom.getRootElement();
Iterator<Element> it = root.elementIterator("photo");
while (it.hasNext()) {
Element e = it.next();
PhotoModel photo = new PhotoModel();
photo.setId(e.attributeValue("id"));
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.elementText("desc"));
list.add(photo);
}
return list;
}
public PhotoModel getSingleById(String id) {
List<PhotoModel> photos = getAll();
for(PhotoModel photo: photos){
if(photo.getId().equals(id)){
return photo;
}
}
return null;
}
public boolean del(String id) {
Document dom = Dom4jFactory.getDom();
Element e = (Element) dom.selectSingleNode("//photo[@id='"+id.trim()+"']");
return e.getParent().remove(e);
}
}
Dom4jFactory
package cn.hncu.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;
import org.dom4j.Document;
import org.dom4j.DocumentException;
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();
// 学习一下服务器下的资源路径加载方式(因为我们的资源已经从MyEclipse中发布到Tomcat服务器中了,所以跟原来纯Java项目不一样了)
// 利用当前类找到它的类加载器,然后通过该类加载器再去获得资源路径
path = Dom4jFactory.class.getClassLoader().getResource("photos.xml")
.getPath();
dom = sax.read(new FileInputStream(path));
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
public static Document getDom(){
return dom;
}
public static boolean save(){
try {
XMLWriter w = new XMLWriter( new FileOutputStream(new File(path)));
w.write(dom);
w.close();
return true;
} catch (Exception e) {
return false;
}
}
}
MyUtils
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 format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static String getCurrentDateTime(){
return format.format(new Date());
}
}
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<h1>我的小相册</h1>
<a href="jsps/upload.jsp">上传相片</a><br/>
<a href="servlets/showServlet">浏览相册</a>
</body>
</html>
upload.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<h1>相处上传</h1>
<form action="<%=request.getContextPath()%>/servlets/uploadServlet"
method="post" enctype="multipart/form-data">
文件:<input type="file" name="file1"/><br/>
说明:<input type="text" name="desc" /><br/>
<input type="submit" value="上传" />
</form>
</body>
</html>
ShowServlet
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.PhotoDao;
public class ShowServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
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>A Servlet</TITLE></HEAD>");
out.println(" <BODY>");
String str ="<table border='1' width='100%'>"+
"<tr><th>文件名</th> <th>上传时间</th> <th>图片</th> <th>说明</th> <th>操作</th> </tr>";
out.println(str);
//显示所有图片
PhotoDao dao = new PhotoDao();
List<PhotoModel> photos = dao.getAll();
for(PhotoModel photo:photos){
out.print("<tr>");
out.print("<td width=100 >"+photo.getRealName()+"</td>");
out.print("<td width=100>"+photo.getDateTime()+"</td>");
//输出图片
String path=request.getContextPath()+"/photos/"+photo.getDir()+"/"+photo.getId()+photo.getExt();
out.print("<td><a href='"+path+"'><img width=200 height=200 src='"+path+"'></img></a></td>");
out.print("<td width=100>"+photo.getDesc()+"</td>");
//操作
String op = "<a href='/photosWeb/servlet/DelServlet?id="+photo.getId()+"'>删除</a> ";
op = op+"<a href='/photosWeb/servlet/DownServlet?id="+photo.getId()+"'>下载</a>";
out.print("<td width=100>"+op+"</td>");
out.print("</tr>");
}
out.println("</table>");
out.println(" </BODY>");
out.println("</HTML>");
out.flush();
out.close();
}
}
DelServlet
package cn.hncu.servlets;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
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.PhotoDao;
public class DelServlet extends HttpServlet {
private PhotoDao dao = new PhotoDao();
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String id = request.getParameter("id");
String ip = request.getRemoteAddr();
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
PhotoModel photo = dao.getSingleById(id);
if(photo!=null){
if(!photo.getIp().equals(ip)){
out.print("你无权删除....");
return;
}
//※※※※以下部分课后补敲的!!!!
//1删除数据库中的信息
boolean boo = dao.del(id);
//2把服务器硬盘中的文件删除
if(boo){
String fileName ="photos/" + photo.getDir()+"/"+photo.getId()+photo.getExt();
String pathFileName = getServletContext().getRealPath(fileName);
File file = new File(pathFileName);
if(file.exists()){
file.delete();
}
String strPath = request.getContextPath()+"/servlets/showServlet";
out.println("相片删除成功!<a href='"+strPath+"'>浏览相册</a>");
}else{
out.println("相片删除失败!");
}
//File file;
//file.delete();
}else{
out.println("该文件不存在!");
}
}
}
DownServlet
package cn.hncu.servlets;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
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.PhotoDao;
public class DownServlet extends HttpServlet {
private PhotoDao dao = new PhotoDao();
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String id = request.getParameter("id");
PhotoModel photo = dao.getSingleById(id);
if(photo!=null){
response.setContentType("application/force-download");
String realName = photo.getRealName();
realName = URLEncoder.encode(realName, "utf-8");
//设置响应头,以让客户端软件下载时能够显示该文件名
response.setHeader("content-Disposition", "attachment;filename=\""+realName+"\"");
String fileName ="photos/" + photo.getDir()+"/"+photo.getId()+photo.getExt();
String pathFileName = getServletContext().getRealPath(fileName);
InputStream in = new FileInputStream(pathFileName);
OutputStream out = response.getOutputStream();
byte buf[] = new byte[1024];
int len=0;
while( (len=in.read(buf))!=-1){
out.write(buf,0,len);
}
out.close();
}else{
response.setContentType("text/html;charset=utf-8");
response.getWriter().println("该文件已经被删除!");
}
}
}
UploadServlet
package cn.hncu.servlets;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
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 org.apache.commons.io.FileUtils;
import cn.hncu.domain.PhotoModel;
import cn.hncu.photoDao.PhotoDao;
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");
PrintWriter out = response.getWriter();
out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
out.println("<HTML>");
out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>");
out.println(" <BODY>");
out.println("不支持get方式上传!");
out.println(" </BODY>");
out.println("</HTML>");
out.flush();
out.close();
}
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>A Servlet</TITLE></HEAD>");
out.println(" <BODY>");
//处理文件上传
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setRepository(new File("d:/a"));
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setSizeMax(1024*1024*10);//最大10M
//upload.setHeaderEncoding("utf-8");//跟下面一行功能相同
request.setCharacterEncoding("utf-8");//上传文件的文件名
FileItem fi=null;
try {
List<FileItem> list = upload.parseRequest(request);
PhotoModel photo = new PhotoModel();//数据封装---需要7个属性
boolean boo=false;
InputStream in = null;
//for循环是把photo的信息封装完整,,,之后(for之后)才能把该photo对象保存到数据库
for(FileItem fii:list){
fi = fii;
if(fi.isFormField()){
String desc = fi.getString("utf-8");//设desc
photo.setDesc(desc);//#1
}else{
in = fi.getInputStream();
String fileName=fi.getName();
if(fileName==null || fileName.trim().equals("")){
out.print("没有选择文件!");
return;
}
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.setId(uuid);//#6
photo.setDir( MyUtils.getDir(uuid) );//#7
}
}
//把相片信息存储到数据库
PhotoDao dao = new PhotoDao();
//System.out.println(photo);
boo = dao.save(photo);//※1※
//如果上面的相片信息保存成功,那么才开始接收图片文件,把它保存到服务器硬盘
if(boo){
String path = getServletContext().getRealPath("/photos");
path = path + "/" + photo.getDir();
File file = new File(path);
if(!file.exists()){
file.mkdirs();
}
String fileName2 = path+"/"+photo.getId()+photo.getExt();
FileUtils.copyInputStreamToFile(in, new File(fileName2));//※2※ 把图片文件存储到服务器硬盘
out.print("上传成功!");
}else{
out.print("上传失败!");
}
} catch (FileUploadException e) {
throw new RuntimeException("上传失败", e);
}finally{
if(fi!=null){
fi.delete();
}
}
out.println(" </BODY>");
out.println("</HTML>");
out.flush();
out.close();
}
}
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>ShowServlet</servlet-name>
<servlet-class>cn.hncu.servlets.ShowServlet</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>/servlets/uploadServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ShowServlet</servlet-name>
<url-pattern>/servlets/showServlet</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>