環境:maven+SpringMVC + Spring + MyBatis + MySql
本文主要說明如何使用input上傳文件到服務器指定目錄,或保存到數據庫中;如何從數據庫下載文件,和顯示圖像文件並實現縮放。
將文件存儲在數據庫中,一般是存文件的byte數組,對應的數據庫數據類型為blob。
首先要創建數據庫,此處使用MySql數據庫。
注意:文中給出的代碼多為節選重要片段,並不齊全。
1. 前期準備
使用maven創建一個springMVC+spring+mybatis+mysql的項目。
關於如何整合Spring+mybatis+mysql,請見MyBatis簡介與配置MyBatis+Spring+MySql:
MyBatis學習之一、MyBatis簡介與配置MyBaits+Spring+MySql
關於SpringMVC環境的搭建請見:使用Eclipse構建Maven的SpringMVC項目:
使用Eclipse構建Maven的SpringMVC項目
在前台html中,form的enctype為multipart/form-data。注意input、select的name要和StudentForm中成員一一對應。
上傳的url為addAction.do,此action方法的參數中使用StudentForm來映射提交的數據。此時就可以獲取到提交的文件的數據。然後我們就對文件進行操作。
創建PHOTO_TBL表:PHOTO_DATA字段用於存放文件,類型為MyBatis的longblob;然後寫Mapper的Java接口PhotoMapper:包括增刪改查;mapper的xml文件:對應JAVA接口的sql語句。
並且需要Spring配置文件添加一個bean的聲明。
下面給出html、action、StudentForm的代碼片段;創建PHOTO_TBL表的sql、PhotoMapper.java接口代碼、PhotoMapper.xml文件代碼。
1.1 html的form表單寫法
1.<form action="<c:url value='addAction.do' />" method="post" enctype="multipart/form-data"> 2. <table> 3. <tr> 4. <td align="right">照片:</td> 5. <td><input type="file" name="studentPhoto"/></td> 6. </tr> 7. </table> 8. <input type="submit"> 9.</form>
1.2 action方法
1./** 2. * 新增- 提交3. */ 4.@RequestMapping(value = "addAction.do") 5.public String add_action(ModelMap model, StudentForm form) { 6. 7.} 1.3 StudentForm類
1.package liming.student.manager.web.model; 2. 3.import org.springframework.web.multipart.MultipartFile; 4. 5.public class StudentForm extends GeneralForm { 6. 7. private String studentName; 8. private int studentSex; 9. private String studentBirthday; 10. private MultipartFile studentPhoto; 11. 12.} 1.4 創建PHOTO_TBL
1.CREATE TABLE PHOTO_TBL 2.( 3. PHOTO_ID VARCHAR(100) PRIMARY KEY, 4. PHOTO_DATA LONGBLOB, 5. FILE_NAME VARCHAR(10) 6.);
1.5 PhotoMapper接口
1.@Repository 2.@Transactional 3.public interface PhotoMapper { 4. 5. public void createPhoto(PhotoEntity entity); 6. 7. public int deletePhotoByPhotoId(String photoId); 8. 9. public int updatePhotoDate(@Param("photoId") String photoId, @Param("photoDate") byte[] photoDate); 10. 11. public PhotoEntity getPhotoEntityByPhotoId(String photoId); 12. 13.} 1.6 PhotoMapper.xml文件
包括增、刪、改、查。其中新增中的photoId使用的是mysql自定義函數自動生成主鍵。在操作blob時需要製定typeHandler為"org.apache.ibatis.type.BlobTypeHandler。insert、update時參數後面需要指定,resultMap中需要指定。
1.<?xml version="1.0" encoding="UTF-8" ?> 2.<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 3.<mapper namespace="liming.student.manager.data.PhotoMapper"> 4. <resultMap type="liming.student.manager.data.model.PhotoEntity" id="photoMapper_resultMap_photoEntity"> 5. <id property="photoId" column="PHOTO_ID" javaType="String" jdbcType="VARCHAR" /> 6. <result property="photoData" column="PHOTO_DATA" javaType="byte[]" jdbcType="BLOB" typeHandler="org.apache.ibatis.type.BlobTypeHandler" /> 7. <result property="fileName" column="FILE_NAME" javaType="String" jdbcType="VARCHAR" /> 8. </resultMap> 9. 10. <insert id="createPhoto" parameterType="liming.student.manager.data.model.PhotoEntity"> 11. <selectKey keyProperty="photoId" resultType="String" order="BEFORE"> 12. select nextval('photo') 13. </selectKey> 14. INSERT INTO PHOTO_TBL(PHOTO_ID, 15. PHOTO_DATA, 16. FILE_NAME) 17. VALUES(#{photoId, jdbcType=VARCHAR}, 18. #{photoData, javaType=byte[], jdbcType=BLOB, typeHandler=org.apache.ibatis.type.BlobTypeHandler}, 19. #{fileName, jdbcType=VARCHAR}) 20. </insert> 21. 22. <delete id="deletePhotoByPhotoId"> 23. DELETE FROM PHOTO_TBL 24. WHERE PHOTO_ID = #{photoId, jdbcType=VARCHAR} 25. </delete> 26. 27. <update id="updatephotoData" > 28. UPDATE PHOTO_TBL 29. SET PHOTO_DATA = #{photoData, javaType=byte[], jdbcType=BLOB, typeHandler=org.apache.ibatis.type.BlobTypeHandler}, 30. FILE_NAME = #{fileName, jdbcType=VARCHAR} 31. WHERE PHOTO_ID = #{photoId, jdbcType=VARCHAR} 32. </update> 33. 34. <select id="getPhotoEntityByPhotoId" resultMap="photoMapper_resultMap_photoEntity"> 35. SELECT PHOTO_ID, 36. PHOTO_DATA, 37. FILE_NAME 38. FROM PHOTO_TBL 39. WHERE PHOTO_ID = #{photoId, jdbcType=VARCHAR} 40. </select> 41.</mapper> 1.7 spring配置文件
需要Spring配置文件添加一個org.springframework.web.multipart.commons.CommonsMultipartResolver的bean的聲明。
1.<bean id="multipartResolver"> 2. <property name="maxUploadSize" value="1073741824" /> 3.</bean>
2. 將文件到服務器上
1.private static final String uploadFilePath = "d://temp_upload_file//"; 2. 3./** 4. * 新增- 提交只保存文件到服務器上5. */ 6.@RequestMapping(value = "addAction.do") 7.public String add_action(ModelMap model, StudentForm form) { 8.try { 9. MultipartFile uploadFile = form.getStudentPhoto(); 10. String filename = uploadFile.getOriginalFilename(); 11. InputStream is = uploadFile.getInputStream(); 12. // 如果服務器已經存在和上傳文件同名的文件,則輸出提示信息13. File tempFile = new File(uploadFilePath + filename); 14. if (tempFile.exists()) { 15. boolean delResult = tempFile.delete(); 16. System.out.println("刪除已存在的文件:" + delResult); 17. } 18. // 開始保存文件到服務器19. if (!filename.equals("")) { 20. FileOutputStream fos = new FileOutputStream(uploadFilePath + filename); 21. byte[] buffer = new byte[8192]; // 每次讀8K字節22. int count = 0; 23. // 開始讀取上傳文件的字節,並將其輸出到服務端的上傳文件輸出流中24. while ((count = is.read(buffer)) > 0) { 25. fos.write(buffer, 0, count); // 向服務端文件寫入字節流26. } 27. fos.close(); // 關閉FileOutputStream對象28. is.close(); // InputStream對象29. } 30. } catch (FileNotFoundException e) { 31. e.printStackTrace(); 32. } catch (IOException e) { 33. e.printStackTrace(); 34. } 35.} 3. 將文件上傳到數據庫中
1./** 2. * 新增- 提交保存文件到數據庫3. */ 4.@RequestMapping(value = "addAction.do") 5.public String add_action(ModelMap model, StudentForm form) { 6. InputStream is = form.getStudentPhoto().getInputStream(); 7. byte[] studentPhotoData = new byte[(int) form.getStudentPhoto().getSize()]; 8. is.read(studentPhotoData); 9. String fileName = form.getStudentPhoto().getOriginalFilename(); 10. PhotoEntity photoEntity = new PhotoEntity(); 11. photoEntity.setPhotoData(studentPhotoData); 12. photoEntity.setFileName(fileName); 13. this.photoMapper.createPhoto(photoEntity); 14.} 4.下載文件
下載文件需要將byte數組還原成文件。
首先使用mybatis將數據庫中的byte數組查出來,指定文件名(包括格式)。然後使用OutputStream將文件輸入
1.@RequestMapping(value = "downPhotoById") 2.public void downPhotoByStudentId(String id, final HttpServletResponse response){ 3. PhotoEntity entity = this.photoMapper.getPhotoEntityByPhotoId(id); 4. byte[] data = entity.getPhotoData(); 5. String fileName = entity.getFileName()== null ? "照片.png" : entity.getFileName(); 6. fileName = URLEncoder.encode(fileName, "UTF-8"); 7. response.reset(); 8. response.setHeader("Content-Disposition", "attachment; filename=/"" + fileName + "/""); 9. response.addHeader("Content-Length", "" + data.length); 10. response.setContentType("application/octet-stream;charset=UTF-8"); 11. OutputStream outputStream = new BufferedOutputStream(response.getOutputStream()); 12. outputStream.write(data); 13. outputStream.flush(); 14. outputStream.close(); 15.}<a href="<%=request.getContextPath() %>/downPhotoById.do?id=8000001">下載照片</a>
5. 顯示byte圖片文件
1.@RequestMapping(value = "getPhotoById") 2.public void getPhotoById (String id, final HttpServletResponse response){ 3. PhotoEntity entity = this.photoMapper.getPhotoEntityByPhotoId(id); 4. byte[] data = entity.getPhotoData(); 5. response.setContentType("image/jpeg"); 6. response.setCharacterEncoding("UTF-8"); 7. OutputStream outputSream = response.getOutputStream(); 8. InputStream in = new ByteArrayInputStream(data); 9. int len = 0; 10. byte[] buf = new byte[1024]; 11. while ((len = in.read(buf, 0, 1024)) != -1) { 12. outputSream.write(buf, 0, len); 13. } 14. outputSream.close(); 15.}<img src="<%=request.getContextPath() %>/getPhotoById.do?id=8000001"/>
6. 按長寬等比例縮放圖片
1.@RequestMapping(value = "getPhotoId") 2.public void getPhotoById (String id, int width, int height, final HttpServletResponse response){ 3. PhotoEntity entity = this.photoMapper.getPhotoEntityByPhotoId(id); 4. byte[] data = entity.getPhotoData(); 5. if (width != 0 && height != 0) { 6. data = scaleImage(data, width, height); 7. } 8. response.setContentType("image/jpeg"); 9. response.setCharacterEncoding("UTF-8"); 10. OutputStream outputSream = response.getOutputStream(); 11. InputStream in = new ByteArrayInputStream(data); 12. int len = 0; 13. byte[] buf = new byte[1024]; 14. while ((len = in.read(buf, 0, 1024)) != -1) { 15. outputSream.write(buf, 0, len); 16. } 17. outputSream.close(); 18.} 19. 20.public static byte[] scaleImage(byte[] data, int width, int height) throws IOException { 21. BufferedImage buffered_oldImage = ImageIO.read(new ByteArrayInputStream(data)); 22. int imageOldWidth = buffered_oldImage.getWidth(); 23. int imageOldHeight = buffered_oldImage.getHeight(); 24. double scale_x = (double) width / imageOldWidth; 25. double scale_y = (double) height / imageOldHeight; 26. double scale_xy = Math.min(scale_x, scale_y); 27. int imageNewWidth = (int) (imageOldWidth * scale_xy); 28. int imageNewHeight = (int) (imageOldHeight * scale_xy); 29. BufferedImage buffered_newImage = new BufferedImage(imageNewWidth, imageNewHeight, BufferedImage.TYPE_INT_RGB); 30. buffered_newImage.getGraphics().drawImage(buffered_oldImage.getScaledInstance(imageNewWidth, imageNewHeight, BufferedImage.SCALE_SMOOTH), 0, 0, null); 31. buffered_newImage.getGraphics().dispose(); 32. ByteArrayOutputStream outPutStream = new ByteArrayOutputStream(); 33. ImageIO.write(buffered_newImage, "jpeg", outPutStream); 34. return outPutStream.toByteArray(); 35.}<img src="<%=request.getContextPath() %>/getPhotoById.do?id=8000001&width=300&height=300"/>
以上所述是小編給大家介紹的MyBatis與SpringMVC相結合實現文件上傳、下載功能,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網網站的支持!