MyBatis与SpringMVC相结合实现文件上传、下载功能
环境: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.1html的form表单写法
1.<formaction="<c:urlvalue='addAction.do'/>"method="post"enctype="multipart/form-data"> 2.<table> 3.<tr> 4.<tdwidth="100"align="right">照片:</td> 5.<td><inputtype="file"name="studentPhoto"/></td> 6.</tr> 7.</table> 8.<inputtype="submit"> 9.</form>
1.2action方法
1./**
2.*新增-提交
3.*/
4.@RequestMapping(value="addAction.do")
5.publicStringadd_action(ModelMapmodel,StudentFormform){
6.
7.}
1.3StudentForm类
1.packageliming.student.manager.web.model;
2.
3.importorg.springframework.web.multipart.MultipartFile;
4.
5.publicclassStudentFormextendsGeneralForm{
6.
7.privateStringstudentName;
8.privateintstudentSex;
9.privateStringstudentBirthday;
10.privateMultipartFilestudentPhoto;
11.
12.}
1.4创建PHOTO_TBL
1.CREATETABLEPHOTO_TBL 2.( 3.PHOTO_IDVARCHAR(100)PRIMARYKEY, 4.PHOTO_DATALONGBLOB, 5.FILE_NAMEVARCHAR(10) 6.);
1.5PhotoMapper接口
1.@Repository
2.@Transactional
3.publicinterfacePhotoMapper{
4.
5.publicvoidcreatePhoto(PhotoEntityentity);
6.
7.publicintdeletePhotoByPhotoId(StringphotoId);
8.
9.publicintupdatePhotoDate(@Param("photoId")StringphotoId,@Param("photoDate")byte[]photoDate);
10.
11.publicPhotoEntitygetPhotoEntityByPhotoId(StringphotoId);
12.
13.}
1.6PhotoMapper.xml文件
包括增、删、改、查。其中新增中的photoId使用的是mysql自定义函数自动生成主键。在操作blob时需要制定typeHandler为"org.apache.ibatis.type.BlobTypeHandler。insert、update时参数后面需要指定,resultMap中需要指定。
1.<?xmlversion="1.0"encoding="UTF-8"?>
2.<!DOCTYPEmapperPUBLIC"-//mybatis.org//DTDMapper3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3.<mappernamespace="liming.student.manager.data.PhotoMapper">
4.<resultMaptype="liming.student.manager.data.model.PhotoEntity"id="photoMapper_resultMap_photoEntity">
5.<idproperty="photoId"column="PHOTO_ID"javaType="String"jdbcType="VARCHAR"/>
6.<resultproperty="photoData"column="PHOTO_DATA"javaType="byte[]"jdbcType="BLOB"typeHandler="org.apache.ibatis.type.BlobTypeHandler"/>
7.<resultproperty="fileName"column="FILE_NAME"javaType="String"jdbcType="VARCHAR"/>
8.</resultMap>
9.
10.<insertid="createPhoto"parameterType="liming.student.manager.data.model.PhotoEntity">
11.<selectKeykeyProperty="photoId"resultType="String"order="BEFORE">
12.selectnextval('photo')
13.</selectKey>
14.INSERTINTOPHOTO_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.<deleteid="deletePhotoByPhotoId">
23.DELETEFROMPHOTO_TBL
24.WHEREPHOTO_ID=#{photoId,jdbcType=VARCHAR}
25.</delete>
26.
27.<updateid="updatephotoData">
28.UPDATEPHOTO_TBL
29.SETPHOTO_DATA=#{photoData,javaType=byte[],jdbcType=BLOB,typeHandler=org.apache.ibatis.type.BlobTypeHandler},
30.FILE_NAME=#{fileName,jdbcType=VARCHAR}
31.WHEREPHOTO_ID=#{photoId,jdbcType=VARCHAR}
32.</update>
33.
34.<selectid="getPhotoEntityByPhotoId"resultMap="photoMapper_resultMap_photoEntity">
35.SELECTPHOTO_ID,
36.PHOTO_DATA,
37.FILE_NAME
38.FROMPHOTO_TBL
39.WHEREPHOTO_ID=#{photoId,jdbcType=VARCHAR}
40.</select>
41.</mapper>
1.7spring配置文件
需要Spring配置文件添加一个org.springframework.web.multipart.commons.CommonsMultipartResolver的bean的声明。
1.<beanid="multipartResolver"class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> 2.<propertyname="maxUploadSize"value="1073741824"/> 3.</bean>
2.将文件到服务器上
1.privatestaticfinalStringuploadFilePath="d:\\temp_upload_file\\";
2.
3./**
4.*新增-提交–只保存文件到服务器上
5.*/
6.@RequestMapping(value="addAction.do")
7.publicStringadd_action(ModelMapmodel,StudentFormform){
8.try{
9.MultipartFileuploadFile=form.getStudentPhoto();
10.Stringfilename=uploadFile.getOriginalFilename();
11.InputStreamis=uploadFile.getInputStream();
12.//如果服务器已经存在和上传文件同名的文件,则输出提示信息
13.FiletempFile=newFile(uploadFilePath+filename);
14.if(tempFile.exists()){
15.booleandelResult=tempFile.delete();
16.System.out.println("删除已存在的文件:"+delResult);
17.}
18.//开始保存文件到服务器
19.if(!filename.equals("")){
20.FileOutputStreamfos=newFileOutputStream(uploadFilePath+filename);
21.byte[]buffer=newbyte[8192];//每次读8K字节
22.intcount=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(FileNotFoundExceptione){
31.e.printStackTrace();
32.}catch(IOExceptione){
33.e.printStackTrace();
34.}
35.}
3.将文件上传到数据库中
1./**
2.*新增-提交–保存文件到数据库
3.*/
4.@RequestMapping(value="addAction.do")
5.publicStringadd_action(ModelMapmodel,StudentFormform){
6.InputStreamis=form.getStudentPhoto().getInputStream();
7.byte[]studentPhotoData=newbyte[(int)form.getStudentPhoto().getSize()];
8.is.read(studentPhotoData);
9.StringfileName=form.getStudentPhoto().getOriginalFilename();
10.PhotoEntityphotoEntity=newPhotoEntity();
11.photoEntity.setPhotoData(studentPhotoData);
12.photoEntity.setFileName(fileName);
13.this.photoMapper.createPhoto(photoEntity);
14.}
4.下载文件
下载文件需要将byte数组还原成文件。
首先使用mybatis将数据库中的byte数组查出来,指定文件名(包括格式)。然后使用OutputStream将文件输入
1.@RequestMapping(value="downPhotoById")
2.publicvoiddownPhotoByStudentId(Stringid,finalHttpServletResponseresponse){
3.PhotoEntityentity=this.photoMapper.getPhotoEntityByPhotoId(id);
4.byte[]data=entity.getPhotoData();
5.StringfileName=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.OutputStreamoutputStream=newBufferedOutputStream(response.getOutputStream());
12.outputStream.write(data);
13.outputStream.flush();
14.outputStream.close();
15.}
<ahref="<%=request.getContextPath()%>/downPhotoById.do?id=8000001">下载照片</a>
5.显示byte图片文件
1.@RequestMapping(value="getPhotoById")
2.publicvoidgetPhotoById(Stringid,finalHttpServletResponseresponse){
3.PhotoEntityentity=this.photoMapper.getPhotoEntityByPhotoId(id);
4.byte[]data=entity.getPhotoData();
5.response.setContentType("image/jpeg");
6.response.setCharacterEncoding("UTF-8");
7.OutputStreamoutputSream=response.getOutputStream();
8.InputStreamin=newByteArrayInputStream(data);
9.intlen=0;
10.byte[]buf=newbyte[1024];
11.while((len=in.read(buf,0,1024))!=-1){
12.outputSream.write(buf,0,len);
13.}
14.outputSream.close();
15.}
<imgsrc="<%=request.getContextPath()%>/getPhotoById.do?id=8000001"/>
6.按长宽等比例缩放图片
1.@RequestMapping(value="getPhotoId")
2.publicvoidgetPhotoById(Stringid,intwidth,intheight,finalHttpServletResponseresponse){
3.PhotoEntityentity=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.OutputStreamoutputSream=response.getOutputStream();
11.InputStreamin=newByteArrayInputStream(data);
12.intlen=0;
13.byte[]buf=newbyte[1024];
14.while((len=in.read(buf,0,1024))!=-1){
15.outputSream.write(buf,0,len);
16.}
17.outputSream.close();
18.}
19.
20.publicstaticbyte[]scaleImage(byte[]data,intwidth,intheight)throwsIOException{
21.BufferedImagebuffered_oldImage=ImageIO.read(newByteArrayInputStream(data));
22.intimageOldWidth=buffered_oldImage.getWidth();
23.intimageOldHeight=buffered_oldImage.getHeight();
24.doublescale_x=(double)width/imageOldWidth;
25.doublescale_y=(double)height/imageOldHeight;
26.doublescale_xy=Math.min(scale_x,scale_y);
27.intimageNewWidth=(int)(imageOldWidth*scale_xy);
28.intimageNewHeight=(int)(imageOldHeight*scale_xy);
29.BufferedImagebuffered_newImage=newBufferedImage(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.ByteArrayOutputStreamoutPutStream=newByteArrayOutputStream();
33.ImageIO.write(buffered_newImage,"jpeg",outPutStream);
34.returnoutPutStream.toByteArray();
35.}
<imgsrc="<%=request.getContextPath()%>/getPhotoById.do?id=8000001&width=300&height=300"/>
以上所述是小编给大家介绍的MyBatis与SpringMVC相结合实现文件上传、下载功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!