文件的上传 连接数据库
-
TinyBlob 最大 255
-
Blob 最大 65K
-
MediumBlob 最大 16M
-
LongBlob 最大 4G
-
-
-
-
-
架构
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" src="${pageContext.request.contextPath }/scripts/jquery-1.7.2.js"></script>
<script type="text/javascript">
//在 upload.jsp 页面上使用 jQuery 实现 "新增一个附件", "删除附件". 但至少需要保留一个.
//对文件的扩展名和大小进行验证 扩展名 .pptx,.docx,.doc
/*1.文件大小不能超过1兆 总的文件大小不能超过5兆
若 验证失败 显示 xxx不合法 文件大小超过1兆
2. 若验证通过 进行上传 文件名不能重复 但是扩展名不能变*/
$(function(){
//第一个是固定的
var i=2;
//获取 addFile 并为其添加 click响应函数
$("#addFile").click(function(){
//注意空格
/*<td >File1:</td>
<td><input type="file" name="file1"/></td> */
//addFile 即添加一个附件 button -->td-->tr
$(this).parent().parent().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的添加时的索引和 i一样
//以前那个值因为 i++ 所以i-1
$("#delete"+(i-1)).click(function(){
alert(i);
// button-->td-->tr
var $tr=$(this).parent().parent();
//删除它的前一个和它本身 tr
$tr.prev("tr").remove();
$tr.remove();
//对 所有的tr 重新排序 两行都重新排序 index从0开始
$(".file").each(function(index){
var n=index+1;
$(this).find("td:first").text("File"+n);//File1
$(this).find("td:last input").attr("name","file"+n);//name="file1"
});
$(".desc").each(function(index){
var n=index + 1;
$(this).find("td:first").text("Desc"+n);
$(this).find("td:last input").attr("name","desc"+n);
});
i=i-1;
})
return false;
})
})
</script>
</head>
<body>
<font color="red" >${message }</font>
<form action="uploadserlvet" method="post" enctype="multipart/form-data">
<input />
<table>
<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>
<td><input type="submit" id="submit" vlaue="提交"/></td>
<td><button id="addFile">新增一个附件</button></td>
</tr>
</table>
</form>
</body>
</html>
package com.greatest.flie.servlet;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
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 org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.FileCleanerCleanup;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileCleaningTracker;
import com.greatest.db.FileUploadBean;
import com.greatest.db.UploadFileDao;
import com.greatest.flie.utils.FileUploadAppProperties;
import com.greatest.flie.utils.FileUtils;
@WebServlet("/app/uploadserlvet")
public class UploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
//绝对路径
private static final String FILE_PATH = "/WEB-INF/files/";
private static final String TEMP_DIP="D:\\tempDirectory";
private UploadFileDao dao=new UploadFileDao ();
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// String exts=FileUploadAppProperties.getInstance().getProperty("exts");
// String fileMaxSize=FileUploadAppProperties.getInstance().getProperty("file.max.size");
// String totalFileMaxSize=FileUploadAppProperties.getInstance().getProperty("total.file.max.size");
// System.out.println(exts);
// System.out.println(fileMaxSize);
// System.out.println(totalFileMaxSize);
// }
request.setCharacterEncoding("UTF-8");
String path=null;
System.out.println("2323");
ServletFileUpload upload = getServletUpload();
try {// 包含最终要放 的 文件名 把需要上传的FileItems 都放入到该Map中
// 键:文件的待存放的路径(文件名) 值:对应的FileItem对象
Map<String, FileItem> uploadFiles = new HashMap<String, FileItem>();
// 解析请求得到FileItem的集合表单域和 文件域
List<FileItem> items = upload.parseRequest(request);
// 1.构建FileUploadBean的集合 有文件名 同时填充uploadFiles
List<FileUploadBean> beans = buliFileUploadBeans(items, uploadFiles);
// 2.校验扩展名
vaidateExtName(beans);
// 3.校验文件大小,在解析时已经校验了*(设置最大值) 我们只需要通过异常得到结果
//源码
// 4.进行文件的上传操作 文件呢?是个集合 输入流 文件名 需要文件名和文件
upload(uploadFiles);
// 5.把上传的信息保存到数据库中
saveFileUploadBeans(beans);
//6.删除临时文件夹的文件
FileUtils.delAllFile(TEMP_DIP);
//成功的话
path="/app/success.jsp";
} catch (Exception e) {
e.printStackTrace();
path="/app/upload.jsp";
request.setAttribute("message", e.getMessage());
}
request.getRequestDispatcher(path).forward(request, response);
}
/*利用传入的FileItem的集合构建FileUploadBean的集合 ,同时填充 uploadFiles
* FileUploadBean对象封装了 id fileName filepath filedesc
* uploadfiles:Map<String , FileItem> 类型 存放的文件域类型的FileItem
* 键 : 袋保存的文件的名字 值:FileItem的对象
* 构建过程 :
* 1.对传入的FileItem集合进行遍历 得到desc的那个Map 键\:desc的 fIELDnAME(desc1,desc2)
* 值 desc的那个输入的文本值
* 2.对传入的FileItem的集合进行遍历 得到的文件域的那些FileItem对象 构建对应的Key(desc1...)来
* 构建FileUploadBean对象 并填充 beans和 uploadFiles */
private List<FileUploadBean> buliFileUploadBeans(List<FileItem> items, Map<String, FileItem> uploadFiles) throws Exception {
//一个Bean对象对应两个FileItem对象( fileItem文件域, 表单域
List<FileUploadBean> beans = new ArrayList<>();
// 1.遍历FileItem的集合先得到desc的Map<String ,String
// >.其中键:fileName(desc1.desc2..),
// 值 :(表单域对应字段的值) desc1.desc2.对应的值
Map<String, String> descs = new HashMap<>();
for (int i=0;i<items.size();i++) {
FileItem item=items.get(i);//返回列表中指定位置的元素。
if (item.isFormField()) {
//保存起来
descs.put(item.getFieldName(),item.getString("UTF-8"));
} }
// 2.在遍历FileItem的集合,得到文件域的FileItem的对象
// 每个得到一个FileItem 对象都创建一个FileUploadBean对象
// 得到fileName构建filePath。从一的 Map中得到当前FileItem对应的那个desc
// 使用fieldName后面的数字去匹配
for (int i=0;i<items.size();i++) {
FileItem item=items.get(i);
FileUploadBean bean=null;
if (!item.isFormField()) {
String fieldName = item.getFieldName();
System.out.println("fieldName"+fieldName);//fieldName file1
//获取最后一个值
String index = fieldName.substring(fieldName.length() - 1);
String filename = item.getName();
String desc = descs.get("desc" + index);
// 获取的文件名与扩展名一致
String filepath = getFilePath(filename);
//把文件路径传给Bean 注意Bean的构造器 参数位置
bean = new FileUploadBean(filename, desc, filepath);
beans.add(bean);
uploadFiles.put(bean.getFilepath(), item);
} }
return beans; }
/*根据给顶的文件名构建一个 随即的文件名
* 1.构建的文件的文件名 扩展名和给定的文件的扩展名一致
* 2.利用ServletContext的getReanlPath方法获取的绝对路径
* 3.利用了 Random和当前的系统时间构建随机文件的名字 * */
private String getFilePath(String filename) {
String extName = filename.substring(filename.lastIndexOf("."));
// filepath是最终的绝对路径 随机数
Random random = new Random();
int randomnumber = random.nextInt(1212121212);
String filepath = getServletContext().getRealPath(FILE_PATH) + "\\" + System.currentTimeMillis()
+ extName + randomnumber;
return filepath;
}
//上传文件
private void upload(Map<String, FileItem> uploadFiles) throws Exception {
//找到文件 遍历
for(Map.Entry<String, FileItem> uploadFile: uploadFiles.entrySet()){
String filepath=uploadFile.getKey();
FileItem item=uploadFile.getValue();
//上传
upload(filepath,item.getInputStream());
} }
//上传的方法
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();
System.out.println("filepath "+filepath);
}
// 与数据库相连接
private void saveFileUploadBeans(List<FileUploadBean> beans) {
dao.save(beans);
}
//检验扩展名合不合法
private void vaidateExtName(List<FileUploadBean> beans) {
String exts = ("pptx,docx,doc,jar");
List<String > extList=Arrays.asList(exts.split(","));
for(FileUploadBean bean:beans){
String fileName=bean.getFilename();
System.out.println("扩展名:查找字符或者子串第一次出现的地方"+fileName.indexOf("."));
String extName=fileName.substring(fileName.lastIndexOf(".")+1);//加一 点不要
System.out.println("扩展名:"+extName);
if(!extList.contains(extName)){
throw new InvalidExtNameException(fileName+"文件的扩展名不合法!!!");
}
}
}
/*构建ServletFileUpload对象
* 从配置文件中读取了部分属性 用户设置约束
* 该方法代码来源于文档
* Alt+Shift+M 抽像成一个方法
* */
private ServletFileUpload getServletUpload() {
String exts=FileUploadAppProperties.getInstance().getProperty("exts");
String fileMaxSize=FileUploadAppProperties.getInstance().getProperty("file.max.size");
String totalFileMaxSize=FileUploadAppProperties.getInstance().getProperty("total.file.max.size");
DiskFileItemFactory factory = new DiskFileItemFactory();
// 设置内存中最多可以存放的上传文件的大小, 若超出则把文件写到一个临时文件夹中. 以 byte 为单位
factory.setSizeThreshold(Integer.parseInt(fileMaxSize));
// 设置那个临时文件夹
File tempDirectory = new File("D:\\tempDirectory");
factory.setRepository(tempDirectory);
// 新建一个文件上传处理程序
ServletFileUpload upload = new ServletFileUpload(factory);
// 设置上传文件的总的大小. 也可以设置单个文件的大小.
upload.setSizeMax(Integer.parseInt(totalFileMaxSize));
upload.setFileSizeMax(Integer.parseInt(fileMaxSize));
return upload;
}
}
package com.greatest.flie.listener;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import org.junit.Test;
import com.greatest.flie.utils.FileUploadAppProperties;
@WebListener
public class FileUploadListener implements ServletContextListener {
//当WEB 应用创建时触发 读取值
@Test
public void contextDestroyed(ServletContextEvent arg0) {
}
//可配置的
public void contextInitialized(ServletContextEvent arg0) {
InputStream in = getClass().getClassLoader().getResourceAsStream("/upload.properties");
Properties properties = new Properties();
try {
properties.load(in);
//遍历
for(Map.Entry<Object, Object> prop: properties.entrySet()){
String propertyName = (String) prop.getKey();//file.max.size。。。
String propertyValue = (String) prop.getValue();//1048576。。。
//传给单例类 Map
FileUploadAppProperties.getInstance().addProperty(propertyName, propertyValue);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.greatest.db;
import java.sql.Connection;
import java.util.List;
public class UploadFileDao extends DAO<FileUploadBean>{
public List<FileUploadBean> getFiles(){
Connection con = null;
try {
con = JDBCUtils.getConnection();
String sql = "SELECT id, file_name fileName, file_path filePath, " +
"file_desc fileDesc FROM upload_files";
return getForList(con , sql);
} catch (Exception e) {
e.printStackTrace();
} finally{
JDBCUtils.releaseConnection(con);
}
return null;
}
public void save(List<FileUploadBean> uploadFiles){
Connection con = null;
try {
con = JDBCUtils.getConnection();
String sql = "INSERT INTO upload_files(file_name, file_path, file_desc) VALUES " +
"(?, ?, ?)";
for(FileUploadBean file: uploadFiles){
update(con, sql, file.getFilename(), file.getFilepath(), file.getFiledesc());
}
} catch (Exception e) {
e.printStackTrace();
} finally{
JDBCUtils.releaseConnection(con);
}
}
}
JavaBean:
public class FileUploadBean {
private Integer id;
//文件名
private String filename;
//文件的路径
private String filepath;
// 文件的描述
private String filedesc;
package com.greatest.db;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ArrayHandler;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
public class DAO<T>{
public static QueryRunner runner = new QueryRunner();
private Class<T> clazz;
public DAO() {
Type type = getClass().getGenericSuperclass();
if(type instanceof ParameterizedType){
ParameterizedType pt = (ParameterizedType) type;
Type [] parameterArgs = pt.getActualTypeArguments();
if(parameterArgs != null && parameterArgs.length > 0){
if(parameterArgs[0] instanceof Class){
clazz = (Class<T>) parameterArgs[0];
}
}
}
}
protected void update(Connection conn, String sql, Object ... args) throws SQLException{
runner.update(conn, sql, args);
}
protected T get(Connection conn, String sql, Object ... args) throws SQLException{
return runner.query(conn, sql, new BeanHandler<>(clazz), args);
}
protected List<T> getForList(Connection conn, String sql, Object ... args) throws SQLException{
return runner.query(conn, sql, new BeanListHandler<>(clazz), args);
}
protected <E> E getValue(Connection conn, String sql, Object ... args) throws SQLException{
E result = null;
result = (E) runner.query(conn, sql, new ArrayHandler(), args)[0];
return result;
}
}
package com.greatest.db;
public class DBException extends RuntimeException {
/**
*
*/
private static final long serialVersionUID = 1L;
public DBException() {
// TODO Auto-generated constructor stub
}
public DBException(String msg) {
super(msg);
}
public DBException(String msg, Exception ex) {
super(msg, ex);
}
}