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.1 html的form表单写法
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.@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" class="org.springframework.web.multipart.commons.commonsmultipartresolver"> 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相结合实现文件上传、下载功能,希望对大家有所帮助
上一篇: 一种很神奇但是也很有意思的分组方式
下一篇: Java程序员面试中的多线程问题总结