檔案的上傳 連線資料庫
阿新 • • 發佈:2018-11-04
-
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);
}
}