前言
剛開始本來只想來測試一下Thumbnails生成縮略圖的效果的,順便來學一下jsp文件,開始沒有使用commons-fileupload上傳組件,自己用純jsp代碼來編寫,過程相當曲折。所以就不建議大家去編寫純JSP的上傳代碼了,想寫的可以參考下commons-fileupload的源碼,裡面很詳細。
一、JSP上傳文件
大家都知道,上傳文件是以二進制上傳的,這樣可以讓文件上傳,所以JSP要做到將文件以二進制上傳,我們再HTML的表單提交時就要設置enctype="multipart/form-data",這個大家應該都很清楚了。
首先我先將jar包引用列出來,大家先找好這幾個jar文件,引入項目
commons-fileupload-1.2.2.jar
commons-io-2.0.1.jar
thumbnailator-0.4.2.jar
先上一下上傳頁面的JSP代碼,其實很簡單,放一個file文件選擇框就可以,我為了測試,順便加了一個文本框。
index.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>縮略圖生成示例</title> </head> <body> <h1>上傳圖片</h1> <form name="uploadForm" action="upload.jsp" method="post" enctype="multipart/form-data"> <input type="text" name="name" /> <input type="file" name="imgPath" /> <input type="submit" value="提交" /> </form> </body> </html>
<%@page import="net.coobird.thumbnailator.Thumbnails"%> <%@page import="org.apache.commons.fileupload.FileItem"%> <%@page import="java.util.Iterator"%> <%@page import="java.util.Hashtable"%> <%@page import="java.util.Map"%> <%@page import="org.apache.commons.fileupload.FileUploadException"%> <%@page import="java.util.List"%> <%@page import="org.apache.commons.fileupload.disk.DiskFileItemFactory"%> <%@page import="org.apache.commons.fileupload.FileItemFactory"%> <%@page import="org.apache.commons.fileupload.servlet.ServletFileUpload"%> <%@page import="java.io.File"%> <%@page contentType="text/html" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>JSP Page</title> </head> <body> <% request.setCharacterEncoding("UTF-8"); String name = ""; String imgPath = ""; String filePath = ""; if (ServletFileUpload.isMultipartContent(request)) { try { FileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(factory); upload.setHeaderEncoding("UTF-8"); upload.setFileSizeMax(1024000L);//單個上傳文件最大值 upload.setSizeMax(2048000L);//整個請求的大小最大值 List list = upload.parseRequest(request); Map _fields = new Hashtable(); Iterator it = list.iterator(); String tempPath = request.getRealPath("/temp/"); String UUID = java.util.UUID.randomUUID().toString(); while (it.hasNext()) { FileItem item = (FileItem) it.next(); if (!item.isFormField()) { String fileImg = item.getName(); //獲取圖片後綴 String suffix = fileImg.substring(fileImg.lastIndexOf(".") , fileImg.length()); filePath = tempPath + File.separator + UUID + suffix; // 建立目標文件 File file = new File(filePath); //將文件寫入到臨時文件上傳目錄 item.write(file); _fields.put(item.getFieldName(), UUID + suffix); } else { _fields.put(item.getFieldName(), item.getString()); } } name = _fields.get("name").toString(); imgPath = _fields.get("imgPath").toString(); String imgPath_s = imgPath.substring(0, imgPath.lastIndexOf(".")); String imgPath_s_suffix = imgPath.substring(imgPath.lastIndexOf(".") , imgPath.length()); //生成縮略圖 String filePath_s_w = tempPath + File.separator + imgPath_s + "_w" + imgPath_s_suffix; String filePath_s_h = tempPath + File.separator + imgPath_s + "_h" + imgPath_s_suffix; String filePath_s_m = tempPath + File.separator + imgPath_s + "_m" + imgPath_s_suffix; //寬為准 Thumbnails.of(filePath) .size(300, 200) .toFile(filePath_s_w); //中圖 Thumbnails.of(filePath) .size(500, 400) .toFile(filePath_s_m); //高為准 Thumbnails.of(filePath) .size(200, 300) .toFile(filePath_s_h); } catch (Exception e) { out.write(e.getMessage()); e.printStackTrace(); } } else { name = request.getParameter("name"); imgPath = request.getParameter("imgPath"); } %> name:<%=name%><br /> imgPath<%=imgPath%><br /> </body> </html>
我就代碼簡單說明一下,我們用ServletFileUpload.isMultipartContent(request)來判斷用戶的表單是否是以二進制上傳,從而改變獲取提交表單數據的模式,因為從二進制裡提交的表單,你從request.getParameter中是獲取不到值的。
通過commons-fileupload組建,我們很容易的獲取到了用戶表單上傳文件流,並保持到了我們服務器磁盤中。
此示例組要是測試圖片生成縮略圖,所以就沒考慮上傳的文件類型,我就當上傳的圖片類型了,如果上傳其他類型的文件,頁面會異常,但是文件可以上傳的。
好我們來看下生成縮略圖的代碼,僅僅簡單的一行代碼。
//size(寬度, 高度) /* * 若圖片橫比200小,高比300小,不變 * 若圖片橫比200小,高比300大,高縮小到300,圖片比例不變 * 若圖片橫比200大,高比300小,橫縮小到200,圖片比例不變 * 若圖片橫比200大,高比300大,圖片按比例縮小,橫為200或高為300 */ Thumbnails.of("c:/images/1280x1024.jpg") .size(200, 300) .toFile("c:/200x300.jpg");