基本实现
fileupload.jsp
用表格呈现出文件上传的表单区域,可以添加删除,并保证序号一致
<%--
Created by IntelliJ IDEA.
User: Limbo
Date: 2016/9/27
Time: 23:23
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>File Upload</title>
<script src="js/jquery-1.12.4.js"></script>
<script>
$(function () {
var i = 2;
//添加文件的点击事件
$("#addFile").click(function () {
$("#option").before("<tr class='file'><td>File"+ i +":</td><td><input type='file' name='file"+ i +"'/></td></tr>" +
"<tr class='desc'><td>Desc"+ i +":</td><td><input type='text' name='desc"+ i +"'/><button id='delete"+ i +"'>删除</button></td></tr>");
i++;
//delete按钮的点击事件
$("#delete" + (i - 1)).click(function () {
i--;
//删除当前节点和该节点的前一个节点
var $tr = $(this).parent().parent();
$tr.prev("tr").remove();
$tr.remove();
//保证文件与描述的序号一致
$(".file").each(function (number) {
var n = number + 1;
$(this).find("td:first").text("File"+n+":");
$(this).find("td:last input").attr("name","file" + n);
});
$(".desc").each(function (number) {
var n = number + 1;
$(this).find("td:first").text("Desc" + n + ":");
$(this).find("td:last input").attr("name","desc" + n);
});
});
return false;
});
});
</script>
</head>
<body>
<form action="FileUpload" method="post" enctype="multipart/form-data">
<table border="1px">
<tr class="file">
<td>File1:</td>
<td><input type="file" name="file1"/></td>
</tr>
<tr class="desc">
<td>Desc1:</td>
<td><input type="text" name="desc1"/></td>
</tr>
<tr id="option">
<td><input type="submit" value="提交!" /></td>
<td><button id="addFile">添加文件</button></td>
</tr>
</table>
</form>
<a href="FileListlerServlet">查看现有文件</a>
</body>
</html>
upload.properties
exts=pptx,docx,doc,jpg,png,txt
fileMaxSize=1048576
totalFileMaxSize=5242880
FileUploadListener.java
主要用于读取配置文件,读配置文件需要一开始就读,最好是在创建servlet容器的时候就读
package cn.limbo.fileUpload; /**
* Created by Limbo on 2016/9/28.
*/
import cn.limbo.utils.FileUploadProperties;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import javax.servlet.http.HttpSessionBindingEvent;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
public class FileUploadListener implements ServletContextListener{
// Public constructor is required by servlet spec
public FileUploadListener() {
}
//servlet容器创建的时候自动调用
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
//获取properties文件
InputStream in = getClass().getClassLoader().getResourceAsStream("/upload.properties");
Properties properties = new Properties();
try {
properties.load(in);
//添加到FileUploadProperties类中
for(Map.Entry<Object,Object > prop: properties.entrySet())
{
String propertyName = (String) prop.getKey();
String propertyValue = (String) prop.getValue();
FileUploadProperties.getInstance().addProperty(propertyName,propertyValue);
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
}
FileUploadProperties.java 上传文件的配置文件
package cn.limbo.utils;
import java.util.HashMap;
import java.util.Map;
/**
* Created by Limbo on 2016/9/28.
*/
public class FileUploadProperties {
private Map<String, String> properties = new HashMap<>();
private static FileUploadProperties instance = new FileUploadProperties();
private FileUploadProperties() {
}
public static FileUploadProperties getInstance() {
return instance;
}
public void addProperty(String propertyName, String propertyValue) {
properties.put(propertyName, propertyValue);
}
public String getProperty(String propertyName) {
return properties.get(propertyName);
}
}
FileUpload.java
上传文件的实现
package cn.limbo.fileUpload;
import cn.limbo.fileUpload.beans.UploadFileBean;
import cn.limbo.utils.FileUploadProperties;
import cn.limbo.utils.SaveUploadFiles;
import com.sun.tools.javac.jvm.Items;
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 javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.sql.SQLException;
import java.util.*;
/**
* Created by Limbo on 2016/9/27.
*/
public class FileUpload extends HttpServlet {
private static final String FILE_PATH = "/Users/Limbo/Documents/files/";
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletFileUpload upload = getServletFileUpload();
//将request中传经来的表单转化成一个列表
List<FileItem> items = null;
try {
items = upload.parseRequest(request);
} catch (FileUploadException e) {
e.printStackTrace();
}
// 把需要上传的FileItem都放入到该Map中
//键:文件的待存放的路径 值 对应FileItem 对象
Map<String , FileItem> uploadFiles = new HashMap<>();
//1.构建UploadFileBean的集合,同时填充uploadFiles
List<UploadFileBean> beans = buildUploadFileBean(items,uploadFiles);
//2.进行文件的上传操作
upload(uploadFiles);
//3.把文件上传的信息保存到数据库中
try {
SaveUploadFiles.save(beans);
} catch (SQLException e) {
e.printStackTrace();
}
response.sendRedirect(request.getContextPath() + "/success.jsp");
}
private void upload(Map<String, FileItem> uploadFiles) throws IOException {
for(Map.Entry<String , FileItem> uploadFile : uploadFiles.entrySet())
{
String filePath = uploadFile.getKey();
FileItem item = uploadFile.getValue();
upload(filePath,item.getInputStream());
item.delete();
}
}
private void upload(String filePath, InputStream inputStream) throws IOException {
OutputStream out = new FileOutputStream(filePath);
byte [] buffer = new byte[1024];
int len = 0 ;
while((len = inputStream.read(buffer)) != -1)
{
out.write(buffer,0,len);
}
inputStream.close();
out.close();
}
private List<UploadFileBean> buildUploadFileBean(List<FileItem> items, Map<String, FileItem> uploadFiles)
{
List<UploadFileBean> list = new ArrayList<>();
//1.遍历FileItem的集合,先得到desc的Map<String,String> 其中键是fieldName
//值表单域对应的字段的值
//得到文件域的FileItem对象
//每个得到一个FileItem对象都创建一个UploadFileBean对象
//得到fileName,构建filePath,从1的Map中得到当前的FileItem对应的desc
Map<String ,String > descs = new HashMap<>();
for(FileItem item :items)
{
if(item.isFormField())
{
descs.put(item.getFieldName(),item.getString());
}
}
for(FileItem item :items)
{
if(!item.isFormField())
{
String fieldName = item.getFieldName();
String index = fieldName.substring( fieldName.length() - 1 );
String fileName = item.getName();
String desc = descs.get("desc" + index);
String filePath = getFilePath(fileName);
UploadFileBean bean = new UploadFileBean(fileName,filePath,desc);
list.add(bean);
uploadFiles.put(filePath,item);
}
}
return list;
}
//这个方法保证上传的文件的名字不一样
private String getFilePath(String fileName) {
String extName = fileName.substring(fileName.lastIndexOf("."));
Random random = new Random();
String filePath = FILE_PATH + random.nextLong() + extName;
return filePath;
}
//封装一个方法用于获得upload
private ServletFileUpload getServletFileUpload()
{
String exts = FileUploadProperties.getInstance().getProperty("exts");
String fileMaxSize = FileUploadProperties.getInstance().getProperty("fileMaxSize");
String totalFileMaxSize = FileUploadProperties.getInstance().getProperty("totalFileMaxSize");
//创建一个DiskFileItemFactory用于获取form对象
DiskFileItemFactory factory = new DiskFileItemFactory();
// 添加限制
/**
* setSizeThreshold方法用于设置是否将上传文件已临时文件的形式保存在磁盘的临界值
*(以字节为单位的int值),如果从没有调用该方法设置此临界值,将会采用系统默认值10KB。
* 对应的getSizeThreshold() 方法用来获取此临界值。
*/
factory.setSizeThreshold(1024 * 500);
File file = new File(this.getServletContext().getRealPath("/WEB-INF/temp"));
if(!file.exists() && !file.isDirectory())
{
file.mkdir();
}
factory.setRepository(file);//设置临时文件存储的位置
//创建一个上传的处理器
ServletFileUpload upload = new ServletFileUpload(factory);
//设置编码
upload.setHeaderEncoding("UTF-8");
//设置所有上传文件的大小
upload.setSizeMax(Integer.parseInt(totalFileMaxSize));
//设置所有上传文件的总大小
upload.setFileSizeMax(Integer.parseInt(fileMaxSize));
return upload;
}
}
UploadFileBean.java 用于封装上传的文件的基本信息
package cn.limbo.fileUpload.beans;
/**
* Created by Limbo on 2016/10/2.
*/
public class UploadFileBean {
private Integer id;
private String fileName;
private String filePath;
private String desc;
public UploadFileBean() {
}
public UploadFileBean(Integer id, String fileName, String filePath, String desc) {
this.id = id;
this.fileName = fileName;
this.filePath = filePath;
this.desc = desc;
}
public UploadFileBean(String fileName, String filePath, String desc) {
this.fileName = fileName;
this.filePath = filePath;
this.desc = desc;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
FileListServlet.java
处理文件列表的servlet
package cn.limbo.fileUpload;
import cn.limbo.fileUpload.beans.UploadFileBean;
import cn.limbo.utils.SaveUploadFiles;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
/**
* Created by Limbo on 2016/10/2.
*/
public class FileListServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
List<UploadFileBean> beans = null;
try {
beans = SaveUploadFiles.getList();
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
req.setAttribute("fileList",beans);
req.getRequestDispatcher("/filelist.jsp").forward(req,resp);
}
}
filelist.jsp
可供下载的文件列表
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
Created by IntelliJ IDEA.
User: Limbo
Date: 2016/10/2
Time: 23:31
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<table border="1">
<tr>
<td>文件名</td>
<td>文件描述</td>
<td>操作</td>
</tr>
<c:forEach var="file" items="${requestScope.fileList}">
<tr>
<td>${file.fileName}</td>
<td>${file.desc}</td>
<td><a href="DownloadServlet?fileName=${file.fileName}&filePath=${file.filePath}">下载</a></td>
</tr>
</c:forEach>
</table>
<br><br>
<a href="fileupload.jsp">上传文件</a>
</body>
</html>
DownloadServlet.java
下载文件的servlet
package cn.limbo.fileUpload;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
/**
* Created by Limbo on 2016/10/3.
*/
public class DownloadServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String filePath = req.getParameter("filePath");
String fileName = req.getParameter("fileName");
//设置类型,告诉浏览器这个文件要下载
resp.setContentType("application/x-msdownload");
//设置响应头,让用户自行选择,但是这个对chrome没有用,它会自动下载
resp.setHeader("Content-Disposition","attachment;filename=" + URLEncoder.encode(fileName,"UTF-8"));
//读写文件
OutputStream out = resp.getOutputStream();
InputStream in = new FileInputStream(filePath);
byte [] buffer = new byte[1024];
int len = 0;
while ((len = in.read(buffer)) != -1)
{
out.write(buffer,0,len);
}
in.close();
}
}
保存到数据库
Database.java
获取数据库连接
package cn.limbo.utils;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
* Created by Limbo on 2016/10/2.
*/
public class Database {
private static Connection connection = null;
public Database() {}
public static Connection getConn() throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","123456");
return connection;
}
}
SaveUploadFiles.java
保存和取得文件列表
package cn.limbo.utils;
import cn.limbo.fileUpload.beans.UploadFileBean;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Limbo on 2016/10/2.
*/
public class SaveUploadFiles {
private static Connection connection = null;
private static Statement statement = null;
//保存一个list
public static void save(List<UploadFileBean> list) throws SQLException {
try {
connection = Database.getConn();
statement = connection.createStatement();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
for(UploadFileBean bean : list)
{
String fileName = bean.getFileName();
String filePath = bean.getFilePath();
String desc = bean.getDesc();
String sql = "INSERT INTO file(file_name, file_path, file_desc) " +
"VALUES ('" + fileName + "','" + filePath + "','" + desc + "')";
statement.execute(sql);
}
}
//得到一个list
public static List<UploadFileBean> getList() throws SQLException, ClassNotFoundException {
connection = Database.getConn();
statement = connection.createStatement();
List<UploadFileBean> list = new ArrayList<>();
String sql = "SELECT * FROM file";
ResultSet rs = statement.executeQuery(sql);
while(rs.next())
{
String fileName = rs.getString("file_name");
String filePath = rs.getString("file_path");
String desc = rs.getString("file_desc");
UploadFileBean bean = new UploadFileBean(fileName,filePath,desc);
list.add(bean);
}
return list;
}
}
success.jsp 成功的页面
<%--
Created by IntelliJ IDEA.
User: Limbo
Date: 2016/10/2
Time: 23:28
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<c:out value="上传成功!"></c:out>
<br><br>
<a href="fileupload.jsp">继续上传</a>
<a href="FileListlerServlet">文件列表</a>
</body>
</html>