环境: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
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 创建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自定义函数自动生成主键。在操作blob时需要制定typeHandler为"org.apache.ibatis.type.BlobTypeHandler。insert、update时参数后面需要指定,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配置文件添加一个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. 将文件到服务器上
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. * 新增 - 提交 – 只保存文件到服务器上 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
5
6
7
8
9
10
11
12
13
14
|
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
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相结合实现文件上传、下载功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对服务器之家网站的支持!