java實現多檔案上傳並儲存到資料庫
阿新 • • 發佈:2019-02-20
好久沒有寫部落格了,今天專案裡需要一個功能,即前臺實現多圖片上傳列表,並後臺儲存到mysql中。前臺後臺一起弄,用了半天時間終於搞定了。
實現:前臺Layui實現;後臺servlet+hibernate
不多廢話,先上圖
前臺實現主要是用的layui框架,框架本身提供多檔案上傳列表,但是沒有檢視的功能,我自己實現了圖片檢視的功能,核心程式碼如下:
<div class="layui-upload"> <button type="button" class="layui-btn layui-btn-normal" id="testList">選擇圖片</button> <div class="layui-upload-list"> <table class="layui-table"> <thead> <tr><th>檔名</th> <th>大小</th> <th>狀態</th> <th>操作</th> </tr></thead> <tbody id="demoList"></tbody> </table> </div> <button type="button" class="layui-btn" id="testListAction">開始上傳</button> </div> <script src="./layui/layui.js" charset="utf-8"></script> <!-- 注意:如果你直接複製所有程式碼到本地,上述js路徑需要改成你本地的 --> <script> layui.use('upload', function(){ var $ = layui.jquery ,upload = layui.upload; //多檔案列表示例 var demoListView = $('#demoList') ,uploadListIns = upload.render({ elem: '#testList' ,url: '/upload/' ,accept: 'file' ,multiple: true ,auto: false ,bindAction: '#testListAction' ,choose: function(obj){ var files = this.files = obj.pushFile(); //將每次選擇的檔案追加到檔案佇列 //讀取本地檔案 obj.preview(function(index, file, result){ var tr = $(['<tr id="upload-'+ index +'">' ,'<td>'+ file.name +'</td>' ,'<td>'+ (file.size/1014).toFixed(1) +'kb</td>' ,'<td>等待上傳</td>' ,'<td>' ,'<button class="layui-btn layui-btn-xs demo-look ">檢視</button>' ,'<button class="layui-btn layui-btn-xs demo-reload layui-hide">重傳</button>' ,'<button class="layui-btn layui-btn-xs layui-btn-danger demo-delete">刪除</button>' ,'</td>' ,'</tr>'].join('')); //檢視 tr.find('.demo-look').on('click', function(){ var imgobj = new Image(); //建立新img物件 imgobj.src = result; //指定資料來源 imgobj.className = 'thumb'; var w = $(window).width()-42 , h = $(window).height()-42; layer.open({ title: '預覽', type: 1, area: [w, h], //寬高 content: '<img src="'+ result +'" alt="'+ file.name +'" class="layui-upload-img">' }); }); //單個重傳 tr.find('.demo-reload').on('click', function(){ obj.upload(index, file); }); //刪除 tr.find('.demo-delete').on('click', function(){ delete files[index]; //刪除對應的檔案 tr.remove(); uploadListIns.config.elem.next()[0].value = ''; //清空 input file 值,以免刪除後出現同名檔案不可選 }); demoListView.append(tr); }); } ,done: function(res, index, upload){ if(res.code == 0){ //上傳成功 var tr = demoListView.find('tr#upload-'+ index) ,tds = tr.children(); tds.eq(2).html('<span style="color: #5FB878;">上傳成功</span>'); tds.eq(3).html(''); //清空操作 return delete this.files[index]; //刪除檔案佇列已經上傳成功的檔案 } this.error(index, upload); } ,error: function(index, upload){ var tr = demoListView.find('tr#upload-'+ index) ,tds = tr.children(); tds.eq(2).html('<span style="color: #FF5722;">上傳失敗</span>'); tds.eq(3).find('.demo-reload').removeClass('layui-hide'); //顯示重傳 } }); }); </script>
後臺一個servlet實現將多圖儲存到mysql
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.sql.Blob; import java.sql.SQLException; import java.sql.Timestamp; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.io.InputStream ; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.sql.rowset.serial.SerialBlob; import javax.sql.rowset.serial.SerialException; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.hibernate.Hibernate; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import com.alibaba.fastjson.JSONObject; import com.pctest.po.TestResAttach; public class LayuiUpload extends HttpServlet { // 儲存檔案的目錄 private static String PATH_FOLDER = "/"; // 存放臨時檔案的目錄 private static String TEMP_FOLDER = "/"; /** * Constructor of the object. */ public LayuiUpload() { super(); } /** * Destruction of the servlet. <br> */ public void destroy() { super.destroy(); // Just puts "destroy" string in log // Put your code here } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } public synchronized void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 結果json物件 JSONObject jsonobj = new JSONObject(); int returnTag = -1; String saveName=null; //上傳的檔名 String filename=null; String id = request.getParameter("ID"); System.out.println("id============="+id); try { System.out.println("==========以下為上傳程式碼============"); request.setCharacterEncoding("utf-8"); // 設定編碼 response.setContentType("text/html;charset=UTF-8"); // 獲得磁碟檔案條目工廠 DiskFileItemFactory factory = new DiskFileItemFactory(); // 如果沒以下兩行設定的話,上傳大的 檔案 會佔用 很多記憶體, // 設定暫時存放的 儲存室 , 這個儲存室,可以和 最終儲存檔案 的目錄不同 /** * 原理 它是先存到 暫時儲存室,然後在真正寫到 對應目錄的硬碟上, 按理來說 當上傳一個檔案時,其實是上傳了兩份,第一個是以 * .tem 格式的 然後再將其真正寫到 對應目錄的硬碟上 */ factory.setRepository(new File(TEMP_FOLDER)); // 設定 快取的大小,當上傳檔案的容量超過該快取時,直接放到 暫時儲存室 factory.setSizeThreshold(1024 * 1024); // 高水平的API檔案上傳處理 ServletFileUpload upload = new ServletFileUpload(factory); // 提交上來的資訊都在這個list裡面 // 這意味著可以上傳多個檔案 // 請自行組織程式碼 List<FileItem> list = upload.parseRequest(request); // 獲取上傳的檔案 for (FileItem file : list) { FileItem item = file; // 獲取檔名 filename = getUploadFileName(item); System.out.println("獲取的檔名============================" + filename); String suffix = filename .substring(filename.lastIndexOf(".") + 1); System.out .println("獲取的檔案字尾名=========================" + suffix); String[] regular = { "JPG", "GIF","PNG","JPEG" ,"BMP"}; boolean flag = false; // 判斷檔案格式是否合法 for (String str : regular) { if (suffix.equalsIgnoreCase(str)) { flag = true; } } if (!flag) { returnTag = 0; throw new Exception("檔案格式不合法!"); } // 儲存後的檔名 saveName = new Date().getTime() + filename.substring(filename.lastIndexOf(".")); String fileExt = filename.substring(filename.lastIndexOf(".")+1);//副檔名 InputStream is=item.getInputStream(); FileOutputStream fos=new FileOutputStream(file.getName()); int len=0; byte[] b=new byte[1024]; while((len=is.read(b))!=-1){ fos.write(b, 0, len); } Blob bb = Hibernate.createBlob(b); TestResAttach tt =new TestResAttach(); SessionFactory sf = new Configuration().configure().buildSessionFactory(); tt.setFilebody(bb); tt.setFileName(saveName); tt.setFileType("images/jpg"); tt.setFileExt(fileExt); tt.setFileclass(0); Timestamp createtime = new Timestamp(new Date().getTime()); tt.setCreatetime(createtime); tt.setTestid(82); tt.setByindex(12); Session s = sf.openSession(); s.beginTransaction(); s.save(tt); s.getTransaction().commit(); s.close(); sf.close(); } if (returnTag != -1) { // 請求失敗 jsonobj.put("STATUS", "1"); } else { jsonobj.put("code", 0); } response.getWriter().write(jsonobj.toString()); response.getWriter().close(); } catch (Exception e) { e.printStackTrace(); jsonobj.put("errorCode", 0); response.getWriter().write(jsonobj.toString()); response.getWriter().close(); } } private String getUploadFileName(FileItem item) { // 獲取路徑名 String value = item.getName(); // 索引到最後一個反斜槓 int start = value.lastIndexOf("/"); // 擷取 上傳檔案的 字串名字,加1是 去掉反斜槓, String filename = value.substring(start + 1); return filename; } /** * Initialization of the servlet. <br> * * @throws ServletException if an error occurs */ public void init(ServletConfig config) throws ServletException { ServletContext servletCtx = config.getServletContext(); // 初始化路徑 // 縮圖儲存路徑 PATH_FOLDER = "C:/source/aaa"; System.out.println("儲存縮圖的目錄===========" + PATH_FOLDER); // 存放臨時檔案的目錄,存放xxx.tmp檔案的目錄 TEMP_FOLDER = servletCtx.getRealPath("/temp"); System.out.println("存放臨時檔案的目錄===========" + TEMP_FOLDER); File dir = new File(PATH_FOLDER); if (!dir.isDirectory()) { dir.mkdir(); } File dir2 = new File(TEMP_FOLDER); if (!dir2.isDirectory()) { dir2.mkdir(); } } }
需要注意的一點,圖片儲存在資料庫中的型別是Blob。