环境: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相结合实现文件上传、下载功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对服务器之家网站的支持!