環(huán)境:maven+SpringMVC + Spring + MyBatis + MySql
本文主要說明如何使用input上傳文件到服務(wù)器指定目錄,或保存到數(shù)據(jù)庫中;如何從數(shù)據(jù)庫下載文件,和顯示圖像文件并實(shí)現(xiàn)縮放。
將文件存儲在數(shù)據(jù)庫中,一般是存文件的byte數(shù)組,對應(yīng)的數(shù)據(jù)庫數(shù)據(jù)類型為blob。
首先要?jiǎng)?chuàng)建數(shù)據(jù)庫,此處使用MySql數(shù)據(jù)庫。
注意:文中給出的代碼多為節(jié)選重要片段,并不齊全。
1. 前期準(zhǔn)備
使用maven創(chuàng)建一個(gè)springMVC+spring+mybatis+mysql的項(xiàng)目。
關(guān)于如何整合Spring+mybatis+mysql,請見MyBatis簡介與配置MyBatis+Spring+MySql:
MyBatis學(xué)習(xí) 之 一、MyBatis簡介與配置MyBaits+Spring+MySql
關(guān)于SpringMVC環(huán)境的搭建請見:使用Eclipse構(gòu)建Maven的SpringMVC項(xiàng)目:
使用Eclipse構(gòu)建Maven的SpringMVC項(xiàng)目
在前臺html中,form的enctype為multipart/form-data。注意input、select的name要和StudentForm中成員一一對應(yīng)。
上傳的url為addAction.do,此action方法的參數(shù)中使用StudentForm來映射提交的數(shù)據(jù)。此時(shí)就可以獲取到提交的文件的數(shù)據(jù)。然后我們就對文件進(jìn)行操作。
創(chuàng)建PHOTO_TBL表:PHOTO_DATA字段用于存放文件,類型為MyBatis的longblob;然后寫Mapper的Java接口PhotoMapper:包括增刪改查;mapper的xml文件:對應(yīng)JAVA接口的sql語句。
并且需要Spring配置文件添加一個(gè)bean的聲明。
下面給出html、action、StudentForm的代碼片段;創(chuàng)建PHOTO_TBL表的sql、PhotoMapper.java接口代碼、PhotoMapper.xml文件代碼。
1.1 html的form表單寫法
1
2
3
4
5
6
7
8
9
|
1 .<form action= "<c:url value='addAction.do' />" method= "post" enctype= "multipart/form-data" > 2 . <table> 3 . <tr> 4 . <td width= "100" 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
5
6
7
|
1 . /** 2. * 新增 - 提交 3. */ 4 . @RequestMapping (value = "addAction.do" ) 5 . public String add_action(ModelMap model, StudentForm form) { 6 . 7 .} |
1.3 StudentForm類
1
2
3
4
5
6
7
8
9
10
11
12
|
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 創(chuàng)建PHOTO_TBL
1
2
3
4
5
6
|
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
2
3
4
5
6
7
8
9
10
11
12
13
|
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自定義函數(shù)自動生成主鍵。在操作blob時(shí)需要制定typeHandler為"org.apache.ibatis.type.BlobTypeHandler。insert、update時(shí)參數(shù)后面需要指定,resultMap中需要指定。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
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配置文件添加一個(gè)org.springframework.web.multipart.commons.CommonsMultipartResolver的bean的聲明。
1
2
3
|
1 .<bean id= "multipartResolver" class = "org.springframework.web.multipart.commons.CommonsMultipartResolver" > 2 . <property name= "maxUploadSize" value= "1073741824" /> 3 .</bean> |
2. 將文件到服務(wù)器上
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
1.private static final String uploadFilePath = "d:\\temp_upload_file\\" ; 2. 3. /** 4. * 新增 - 提交 – 只保存文件到服務(wù)器上 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. // 如果服務(wù)器已經(jīng)存在和上傳文件同名的文件,則輸出提示信息 13. File tempFile = new File(uploadFilePath + filename); 14. if (tempFile.exists()) { 15. boolean delResult = tempFile. delete (); 16. System.out.println( "刪除已存在的文件:" + delResult); 17. } 18. // 開始保存文件到服務(wù)器 19. if (!filename.equals( "" )) { 20. FileOutputStream fos = new FileOutputStream(uploadFilePath + filename); 21. byte[] buffer = new byte[8192]; // 每次讀8K字節(jié) 22. int count = 0; 23. // 開始讀取上傳文件的字節(jié),并將其輸出到服務(wù)端的上傳文件輸出流中 24. while ((count = is.read(buffer)) > 0) { 25. fos.write(buffer, 0, count); // 向服務(wù)端文件寫入字節(jié)流 26. } 27. fos.close(); // 關(guān)閉FileOutputStream對象 28. is.close(); // InputStream對象 29. } 30. } catch (FileNotFoundException e) { 31. e.printStackTrace(); 32. } catch (IOException e) { 33. e.printStackTrace(); 34. } 35.} |
3. 將文件上傳到數(shù)據(jù)庫中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
1 . /** 2. * 新增 - 提交 – 保存文件到數(shù)據(jù)庫 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數(shù)組還原成文件。
首先使用mybatis將數(shù)據(jù)庫中的byte數(shù)組查出來,指定文件名(包括格式)。然后使用OutputStream將文件輸入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
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 .} |
1
|
<a href= "<%=request.getContextPath() %>/downPhotoById.do?id=8000001" >下載照片</a> |
5. 顯示byte圖片文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
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 .} |
1
|
<img src= "<%=request.getContextPath() %>/getPhotoById.do?id=8000001" /> |
6. 按長寬等比例縮放圖片
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
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 .} |
1
|
<img src= "<%=request.getContextPath() %>/getPhotoById.do?id=8000001&width=300&height=300" /> |
以上所述是小編給大家介紹的MyBatis與SpringMVC相結(jié)合實(shí)現(xiàn)文件上傳、下載功能,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時(shí)回復(fù)大家的。在此也非常感謝大家對服務(wù)器之家網(wǎng)站的支持!