一.文件上传
文件上传程序步骤
1.如何在web页面中添加上传输入项?
<input type=“file”>标签用于在web页面中添加文件上传输入项,设置文件上传输入项时须注意:
1)、
必须要设置input输入项的name属性,否则浏览器将不会发送上传文件的数据。
2)、必须
把form的enctype属值设为multipart/form-data.设置该值后,浏览器在上传文件时,将把文件数据附带在http请求消息体中,并使用MIME协议对上传的文件进行描述,以方便接收方对上传数据进行解析和处理。
3)、表单的
提交方式要是post
2、服务器端 Servlet读取上传文件内容,保存到服务器端
常见问题:
1、表单控件没写name属性 ----- 上传文件数据不会提交2、表单没有设置enctype enctype="application/x-www-form-urlencoded"
upload=C%3A%5CDocuments+and+Settings%5Cseawind%5C%E6%A1%8C%E9%9D%A2%5C2012%E5%B9%B42%E6%9C%8810%E6%97%A5%E7%8F%AD%5Cj2ee6_docs.chm
* 此时 请求数据包中 没有上传文件数据的
upload=C%3A%5CDocuments+and+Settings%5Cseawind%5C%E6%A1%8C%E9%9D%A2%5C2012%E5%B9%B42%E6%9C%8810%E6%97%A5%E7%8F%AD%5Cday20%5C%E7%AC%94%E8%AE%B0.txt
上传文件请求体格式
当使用enctype后 --- multipart/form-data
上传文件请求体 采用MIME消息格式 格式如下:
Content-Disposition: form-data; name="username"
寮犱笁
-----------------------------7dc2fd10407a8
Content-Disposition: form-data; name="upload"; filename="C:\Documents and Settings\seawind\妗岄潰\info.txt"
Content-Type: text/plain
Iam ok!
today is sunny!
很好!
-----------------------------7dc2fd10407a8--
通过request.getInputStream 获得请求体中包含数据
解析上传文件数据
分析原理之后 需要使用开源技术来解决
1、JSP Smart-upload (产生于JSP盛行时代 Model1)2、 commons-fileupload --- Apache commons项目中一个子项目
* upload jar 依赖 io包 ---- commoms-io
共需要导入两个jar包:
Commons-fileupload和commons-io
上传Servlet
创建文件项 工厂 FileItemFactory
此工厂类常用的方法:
1、SizeThreshold 设置内存缓冲区大小
上传文件时,文件首先是要保存在服务器内存缓冲区内
例如:缓冲区64m 上传200m文件 ---- 将内存缓冲区中数据,保存到硬盘上形成临时文件
2、Repository 设置临时目录
if(!fileItem.isFormField()){// 如果文件项不是一个简单表单域,他就是一个上传文件
}
1、SizeThreshold 设置内存缓冲区大小
上传文件时,文件首先是要保存在服务器内存缓冲区内
例如:缓冲区64m 上传200m文件 ---- 将内存缓冲区中数据,保存到硬盘上形成临时文件
2、Repository 设置临时目录
创建解析器 ServletFileUpload
1、 解析request数据parseRequest ---- FileItem的List
什么是FileItem ----- MIME BodyPart
2、遍历List,寻找哪个是上传文件的FileItemif(!fileItem.isFormField()){// 如果文件项不是一个简单表单域,他就是一个上传文件
}
文件上传API图解:
代码示例:
上传文件jsp示例:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>文件上传 form 表单</h1>
<form action="upload4" method="post" enctype="multipart/form-data">
用户名<input type="text" name="username" /><br/>
上传文件<input type="file" name="upload"/> <!-- 以post提交 数据在请求体中 -->
<input type="submit" />
</form>
</body>
</html>
上传文件servlet示例:
package cn.servlet;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
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;
public class UploadServlet2 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 使用file upload 技术 进行文件上传
// 创建文件项工厂
DiskFileItemFactory factory = new DiskFileItemFactory(); // 目的:存放
// 创建ServletFileUpload
ServletFileUpload servletFileUpload = new ServletFileUpload(factory); // 解析器
// 解析
try {
// 获得文件项列表 -- 每一个文件项相当于 一个上传表单组件
List<FileItem> fileItems = servletFileUpload.parseRequest(request);
System.out.println(fileItems.size());
// 查找哪个是上传文件项
for (FileItem fileItem : fileItems) {
// 判断fileItem是上传文件
if (!fileItem.isFormField()) {
// 上传文件
InputStream in = fileItem.getInputStream();
String fileName = fileItem.getName();
int index = fileName.lastIndexOf("\\");
if (index != -1) {
// 截取文件名
fileName = fileName.substring(index + 1);
}
FileOutputStream out = new FileOutputStream("c:\\"
+ fileName);
int temp;
while ((temp = in.read()) != -1) {
out.write(temp);
}
in.close();
out.close();
}
}
} catch (FileUploadException e) {
e.printStackTrace();
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
若干注意问题:
* 文件上传解析之前 需要先判断 该表单是否为文件上传表单 enctype="multipart/form-data"boolean isMultipart = ServletFileUpload.isMultipartContent(request);
* 对于 上传文件名中文乱码解决 setHeaderEncoding(java.lang.String encoding)
* 监听文件上传过程 setProgressListener(ProgressListener pListener) ------ 开发中结合AJax一起使用 进度条
* 如果form使用文件上传格式multipart ,此时不能再使用request.getParameter获得数据了
使用 getString 获得 普通表单项的值,如果中文乱码 getString(charset) 解决数据乱码
*对于临时文件删除 通过fileItem.delete来实现 ,但是该方法的调用必须位于 fileitem的输入流关闭之后
比较完善的上传代码:
package cn.servlet;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
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;
public class UploadServlet3 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 此方法不能在文件上传 表单中使用
System.out.println(request.getParameter("username"));
// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(1024 * 1024); // 1M 缓存
// 定义一个指向WEB-INF/temp 的临时目录
File tempDir = new File(getServletContext()
.getRealPath("/WEB-INF/temp"));
factory.setRepository(tempDir);
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setSizeMax(1024 * 1024 * 10);// 最大10m
// 解决中文乱码
upload.setHeaderEncoding("utf-8");
// Parse the request
try {
if (ServletFileUpload.isMultipartContent(request)) {
List<FileItem> /* FileItem */items = upload
.parseRequest(request);
for (FileItem fileItem : items) {
if (fileItem.isFormField()) {
// 普通表单域
String fieldName = fileItem.getFieldName();
String value = fileItem.getString("utf-8");// 中文有乱码,getString(charset)
System.out.println(fieldName + ":" + value);
} else {
// 文件上传
String fieldName = fileItem.getFieldName();
String fileName = fileItem.getName();
String contentType = fileItem.getContentType();
boolean isInMemory = fileItem.isInMemory();
long sizeInBytes = fileItem.getSize();
// 不同浏览器发送文件名 可能会含有/ 路径信息
int index = fileName.lastIndexOf("\\");
if (index != -1) {
// 截取文件名
fileName = fileName.substring(index + 1);
}
// 流拷贝
InputStream in = fileItem.getInputStream();
OutputStream out = new FileOutputStream(
getServletContext().getRealPath(
"/WEB-INF/upload" + "/" + fileName));
int temp;
while ((temp = in.read()) != -1) {
out.write(temp);
}
in.close();
out.close();
// 删除临时文件
fileItem.delete();
}
}
} else {
// 不是一个文件上传表单
}
} catch (FileUploadException e) {
e.printStackTrace();
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
文件存放位置问题:
存放文件安全问题: 位于WEB-INF下存放文件时,如果防止文件重名 ------ 使用UUID生成随机码,使用源文件扩展名
问题: 当上传文件数量过多时,存放一个目录,将严重影响性能? 分离目录
分离目录算法
1、按时间分离 月、日、时
2、按用户分离 用户名唯一 目录唯一
3、按格式分离
4、 按照hashCode分离
hashCode示例:
package cn.utils;
import java.util.UUID;
public class UUIDUtils {
public static String generateDir(String fileName) {
// 最多生成8级目录
int hashCode = fileName.hashCode();
int n1 = hashCode & 0xf; // 1级目录
int n2 = hashCode >> 4 & 0xf; // 2级目录
return "/" + n1 + "/" + n2;
}
public static String generateUUID() {
return UUID.randomUUID().toString();
}
// 传入一个文件名,保留扩展名,生成UUID名称
public static String generateRandomFileName(String fileName) {
// 获得扩展名
String ext = fileName.substring(fileName.lastIndexOf("."));
return generateUUID() + ext;
}
}
另外,使用ProgressListener 监控文件上传过程,结合Ajax 来编写文件上传任务可视化进度条(文件大小,剩余大小,上传速度等)。
二.文件下载
原理:将服务器端文件读入内存,通过response输出流写出
编写上传的servlet
编写下载servlet
MIMEUtility ----- FF
Web应用中实现文件下载的两种方式
1.超链接直接指向下载资源
2.程序实现下载
需设置两个响应头:
1)设置Content-Type 的值为:
application/x-
msdownload
。
Web
服务器需要告诉浏览器其所输出的内容的类型不是普通的文本文件或 HTML 文件,
而是一个要保存到本地的下载文件。
2)
Web
服务器希望浏览器不直接处理相应的
实体内容,而是
由用户选择将相应的实体内容保存到一个文件中,这
需要设置
Content-Disposition
报头。该报头指定了接收程序处理数据内容的方式,在 HTTP 应用中
只有
attachment
是标准方式,attachment 表示要求用户干预。在 attachment 后面还可以指定 filename 参数,该参数是服务器建议
浏览器将实体内容保存到文件中的文件名称。在设置 Content-Dispostion 之前一定要指定 Content-Type.
设置示例:
因为要下载的文件可以是各种类型的文件,所以要将文件传送给客户端,其相应内容应该被当做二进制来处理,所以应该调用response.getOutputStream()方法返回 ServeltOutputStream 对象来向客户端写入文件内容。
案例一:遍历上传目录下的所有文件显示给用户,并允许用户完成下载。
代码示例:
首先,编写上传文件代码
上传表单所在jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>文件上传 form 表单</h1>
<form action="upload4" method="post" enctype="multipart/form-data">
用户名<input type="text" name="username" /><br/>
上传文件<input type="file" name="upload"/> <!-- 以post提交 数据在请求体中 -->
<input type="submit" />
</form>
</body>
</html>
编写上传的servlet
package cn.servlet;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
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.utils.UUIDUtils;
public class UploadServlet4 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 此方法不能在文件上传 表单中使用
System.out.println(request.getParameter("username"));
// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(1024 * 1024); // 1M 缓存
// 定义一个指向WEB-INF/temp 的临时目录
File tempDir = new File(getServletContext()
.getRealPath("/WEB-INF/temp"));
factory.setRepository(tempDir);
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setSizeMax(1024 * 1024 * 10);// 最大10m
// 解决中文乱码
upload.setHeaderEncoding("utf-8");
// Parse the request
try {
if (ServletFileUpload.isMultipartContent(request)) {
List<FileItem> /* FileItem */items = upload
.parseRequest(request);
for (FileItem fileItem : items) {
if (fileItem.isFormField()) {
// 普通表单域
String fieldName = fileItem.getFieldName();
String value = fileItem.getString("utf-8");// 中文有乱码,getString(charset)
System.out.println(fieldName + ":" + value);
} else {
// 文件上传
String fieldName = fileItem.getFieldName();
String fileName = fileItem.getName();
String contentType = fileItem.getContentType();
boolean isInMemory = fileItem.isInMemory();
long sizeInBytes = fileItem.getSize();
// 不同浏览器发送文件名 可能会含有/ 路径信息
int index = fileName.lastIndexOf("\\");
if (index != -1) {
// 截取文件名
fileName = fileName.substring(index + 1);
}
// 流拷贝
InputStream in = fileItem.getInputStream();
// 为了防止文件名重复,使用UUID 存放唯一文件名
OutputStream out = new FileOutputStream(
getServletContext()
.getRealPath(
"/WEB-INF/upload"
+ "/"
+ UUIDUtils
.generateRandomFileName(fileName)));
int temp;
while ((temp = in.read()) != -1) {
out.write(temp);
}
in.close();
out.close();
// 删除临时文件
fileItem.delete();
}
}
} else {
// 不是一个文件上传表单
}
} catch (FileUploadException e) {
e.printStackTrace();
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
然后编写下载代码
编写展示所有文件的列表的jsp下载页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@page import="java.io.File"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- 遍历所有上传文件,显示给用户下载 遍历/WEB-INF/upload -->
<%
String path = application.getRealPath("/WEB-INF/upload");
File pathFile = new File(path);
String[] fileNames = pathFile.list();
pageContext.setAttribute("fileNames",fileNames);
%>
<c:forEach var="fileName" items="${fileNames}">
<a href="download?fileName=${fileName }">${fileName }</a><br/>
</c:forEach>
</body>
</html>
编写下载servlet
package cn.servlet;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import javax.mail.internet.MimeUtility;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DownloadServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 从客户端 获得下载文件名称
String fileName = request.getParameter("fileName");
// 处理乱码
fileName = new String(fileName.getBytes("ISO-8859-1"), "utf-8");
// 设置MIME 类型
response.setContentType(getServletContext().getMimeType(fileName));
// 设置以附件形式打开
response.setHeader("Content-Disposition", "attachment;filename="
+ MimeUtility.encodeText(fileName, "utf-8", "B"));
// 获得文件完整路径
// fileName = getServletContext().getRealPath("/" + fileName);
// 下载WEB-INF/upload下文件
fileName = getServletContext().getRealPath(
"/WEB-INF/upload" + "/" + fileName);
// 读取文件
BufferedInputStream in = new BufferedInputStream(new FileInputStream(
fileName));
// 将输入流拷贝到response的输出流中
BufferedOutputStream out = new BufferedOutputStream(response
.getOutputStream());
int temp;
while ((temp = in.read()) != -1) {
out.write(temp);
}
in.close();
out.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
* 对于中文名称下载文件名乱码问题:
URLEncoder ------ IEMIMEUtility ----- FF
案例二:模拟网络硬盘系统
设计图示:
首先添加vo类
package cn.vo;
import java.sql.Date;
public class MyFileItem {
private int id;
private String uuidname; // 上传文件的名称,文件的uuid名
private String realname; // 上传文件的真实名称
private String savepath; // 记住文件的位置
private Date uploadtime; // 文件的上传时间
private String description; // 文件的描述
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUuidname() {
return uuidname;
}
public void setUuidname(String uuidname) {
this.uuidname = uuidname;
}
public String getRealname() {
return realname;
}
public void setRealname(String realname) {
this.realname = realname;
}
public String getSavepath() {
return savepath;
}
public void setSavepath(String savepath) {
this.savepath = savepath;
}
public Date getUploadtime() {
return uploadtime;
}
public void setUploadtime(Date uploadtime) {
this.uploadtime = uploadtime;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
编写upload.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
function checkFormField(){
var realname = document.getElementById("realname").value;
var upload = document.getElementById("upload").value;
var description = document.getElementById("description").innerHTML;
if(realname==""){
alert("文件名不能为空");
return false;
}else if(upload ==""){
alert("必须包含上传文件!");
return false;
}else if(description==""){
alert("文件描述不能为空!");
return false;
}
}
</script>
</head>
<body>
<h1>文件上传</h1>
<form action="${pageContext.request.contextPath }/upload" method="post" enctype="multipart/form-data" οnsubmit="return checkFormField();">
文件名 <input type="text" name="realname" id="realname" /> <br/>
文件描述<textarea rows="3" cols="40" name="description" id="description"></textarea><br/>
<input type="file" name="upload" id="upload"/><br/>
<input type="submit" value="上传" />
</form>
</body>
</html>
按照设计图编写上传servlet
package cn.web.servlet;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Date;
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.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import cn.service.MyFileItemService;
import cn.utils.UploadUtils;
import cn.vo.MyFileItem;
public class UploadServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 1、获得数据 2、保存文件到硬盘 3、保存相关信息到数据库
// 定义javabean对象
MyFileItem myFileItem = new MyFileItem();
if (ServletFileUpload.isMultipartContent(request)) {
DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
ServletFileUpload servletFileUpload = new ServletFileUpload(
diskFileItemFactory);
// 设置上传文件名乱码处理
servletFileUpload.setHeaderEncoding("utf-8");
try {
List<FileItem> fileItems = servletFileUpload
.parseRequest(request);
for (FileItem fileItem : fileItems) {
if (fileItem.isFormField()) {
// 普通表单域
// 获得name和value
String name = fileItem.getFieldName();
String value = fileItem.getString("utf-8");
System.out.println(name + "===" + value);
if (name.equals("realname")) {
myFileItem.setRealname(value);
} else if (name.equals("description")) {
myFileItem.setDescription(value);
}
} else {
// 文件上传域
String name = fileItem.getName();
String contentType = fileItem.getContentType();
InputStream in = new BufferedInputStream(fileItem
.getInputStream());
// 生成唯一文件名
String uuidname = UploadUtils
.generateRandonFileName(name);
// 生成目录
String dir = UploadUtils.generateRandomDir(uuidname);
File dirFile = new File(getServletContext()
.getRealPath("/WEB-INF/upload")
+ dir);
// 此时目录不一定存在
dirFile.mkdirs();
File outputFile = new File(dirFile, uuidname);
OutputStream out = new BufferedOutputStream(
new FileOutputStream(outputFile));
int temp;
while ((temp = in.read()) != -1) {
out.write(temp);
}
in.close();
out.close();
// 删除临时文件
fileItem.delete();
myFileItem.setSavepath(dir); // /8/9
myFileItem.setUuidname(uuidname);
myFileItem.setUploadtime(new Date(System
.currentTimeMillis()));
// 操作数据库保存
MyFileItemService service = new MyFileItemService();
service.addFileItem(myFileItem);
response.getWriter().println("upload success!");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
service:
package cn.service;
import java.util.List;
import cn.itcast.dao.MyFileItemDAO;
import cn.itcast.vo.MyFileItem;
public class MyFileItemService {
public MyFileItem findFileItem(int id) {
return new MyFileItemDAO().findById(id);
}
// 查询所有文件
public List<MyFileItem> listAllFileItems() {
return new MyFileItemDAO().findAll();
}
// 将文件信息存入数据库
public void addFileItem(MyFileItem fileItem) {
new MyFileItemDAO().insert(fileItem);
}
}
dao:
package cn.dao;
import java.sql.SQLException;
import java.util.List;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import cn.utils.JDBCUtils;
import cn.vo.MyFileItem;
public class MyFileItemDAO {
public MyFileItem findById(int id) {//通过id得到需要下载的文件的信息
String sql = "select * from files where id = ?";
QueryRunner queryRunner = new QueryRunner(JDBCUtils.getDataSource());
try {
MyFileItem fileItem = queryRunner.query(sql,
new BeanHandler<MyFileItem>(MyFileItem.class), id);
return fileItem;
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
public List<MyFileItem> findAll() {//得到数据库内所有信息,用来构造所有文件下载显示列表使用
String sql = "select * from files";
QueryRunner queryRunner = new QueryRunner(JDBCUtils.getDataSource());
try {
List<MyFileItem> fileItems = queryRunner.query(sql,
new BeanListHandler<MyFileItem>(MyFileItem.class));
return fileItems;
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
public void insert(MyFileItem myFileItem) {//插入数据库操作
QueryRunner queryRunner = new QueryRunner(JDBCUtils.getDataSource());
String sql = "insert into files values(null,?,?,?,?,?)";
Object[] param = new Object[] { myFileItem.getUuidname(),
myFileItem.getRealname(), myFileItem.getSavepath(),
myFileItem.getUploadtime(), myFileItem.getDescription() };
try {
System.out.println("insert ....");
queryRunner.update(sql, param);
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
得到所有的文件列表servlet
package cn.web.servlet;
import java.io.IOException;
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.service.MyFileItemService;
import cn.vo.MyFileItem;
public class ListServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 查询文件列表 返回客户端
MyFileItemService fileItemService = new MyFileItemService();
List<MyFileItem> fileItems = fileItemService.listAllFileItems();
// 传递jsp显示
request.setAttribute("fileItems", fileItems);
request.getRequestDispatcher("/download.jsp")
.forward(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
下载页面的jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- 显示文件列表 -->
<c:forEach var="fileItem" items="${requestScope.fileItems}">
<a href="${pageContext.request.contextPath }/download?id=${fileItem.id}">${fileItem.realname}</a><br/>
<span>文件描述:${fileItem.description}</span><br/><hr/>
</c:forEach>
</body>
</html>
下载servlet:
package cn.web.servlet;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
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.service.MyFileItemService;
import cn.vo.MyFileItem;
public class DownloadServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String id = request.getParameter("id");
// 查询id 对应文件信息
MyFileItemService fileItemService = new MyFileItemService();
MyFileItem fileItem = fileItemService
.findFileItem(Integer.parseInt(id));
// 设置头信息
response.setContentType(getServletContext().getMimeType(
fileItem.getUuidname()));
response.setHeader("Content-Disposition", "attachment;filename="
+ URLEncoder.encode(fileItem.getRealname(), "utf-8"));
// 根据文件信息 硬盘查找真实文件位置,下载
String filePath = getServletContext().getRealPath("/WEB-INF/upload")
+ fileItem.getSavepath() + "/" + fileItem.getUuidname();
InputStream in = new BufferedInputStream(new FileInputStream(filePath));
OutputStream out = new BufferedOutputStream(response.getOutputStream());
int temp;
while ((temp = in.read()) != -1) {
out.write(temp);
}
in.close();
out.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
即完成案例编写