1. 程式人生 > >檔案的上傳 連線資料庫

檔案的上傳 連線資料庫

  • 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);
	}
}