myBatis + SpringMVC上传、下载文件

转载来自:http://limingnihao.iteye.com/blog/1069503

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表单写法
Html代码 复制代码  收藏代码
  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>  
<form action="<c:url value='addAction.do' />" method="post" enctype="multipart/form-data">			<table>		<tr>			<td width="100" align="right">照片:</td>			<td><input type="file" name="studentPhoto"/></td>		</tr>	</table>	<input type="submit"></form>
 

 

 

1.2 action方法
Java代码 复制代码  收藏代码
  1. /** 
  2.  * 新增 - 提交 
  3.  */  
  4. @RequestMapping(value = "addAction.do")  
  5. public String add_action(ModelMap model, StudentForm form) {  
  6.   
  7. }  
/** * 新增 - 提交 */@RequestMapping(value = "addAction.do")public String add_action(ModelMap model, StudentForm form) {}
 

 

 

1.3 StudentForm类
Java代码 复制代码  收藏代码
  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. }  
package liming.student.manager.web.model;import org.springframework.web.multipart.MultipartFile;public class StudentForm extends GeneralForm {	private String studentName;	private int studentSex;	private String studentBirthday;	private MultipartFile studentPhoto;}
 

 

 

 

1.4 创建PHOTO_TBL
Sql代码 复制代码  收藏代码
  1. CREATE TABLE PHOTO_TBL  
  2. (  
  3.    PHOTO_ID     VARCHAR(100) PRIMARY KEY,  
  4.    PHOTO_DATA   LONGBLOB,  
  5.    FILE_NAME    VARCHAR(10)  
  6. );  
CREATE TABLE PHOTO_TBL(   PHOTO_ID     VARCHAR(100) PRIMARY KEY,   PHOTO_DATA   LONGBLOB,   FILE_NAME    VARCHAR(10));
 

 

 

1.5  PhotoMapper接口
Java代码 复制代码  收藏代码
  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. }  
@Repository@Transactionalpublic interface PhotoMapper {	public void createPhoto(PhotoEntity entity);	public int deletePhotoByPhotoId(String photoId);	public int updatePhotoDate(@Param("photoId") String photoId, @Param("photoDate") byte[] photoDate);	public PhotoEntity getPhotoEntityByPhotoId(String photoId);}
 

 

 

 

1.6  PhotoMapper.xml文件

         包括增、删、改、查。其中新增中的photoId使用的是mysql自定义函数自动生成主键。在操作blob时需要制定typeHandler为"org.apache.ibatis.type.BlobTypeHandler。insert、update时参数后面需要指定,resultMap中需要指定。

 

Xml代码 复制代码  收藏代码
  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>  
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="liming.student.manager.data.PhotoMapper">	<resultMap type="liming.student.manager.data.model.PhotoEntity" id="photoMapper_resultMap_photoEntity">		<id property="photoId"			column="PHOTO_ID" 		javaType="String" jdbcType="VARCHAR" />		<result property="photoData"	column="PHOTO_DATA" 	javaType="byte[]" jdbcType="BLOB" typeHandler="org.apache.ibatis.type.BlobTypeHandler" />		<result property="fileName" 	column="FILE_NAME" 		javaType="String" jdbcType="VARCHAR" />	</resultMap>		<insert id="createPhoto" parameterType="liming.student.manager.data.model.PhotoEntity">		<selectKey keyProperty="photoId" resultType="String" order="BEFORE">			select nextval('photo')		</selectKey>		INSERT INTO PHOTO_TBL(PHOTO_ID,						      PHOTO_DATA,						      FILE_NAME)		VALUES(#{photoId, jdbcType=VARCHAR},			   #{photoData, javaType=byte[], jdbcType=BLOB, typeHandler=org.apache.ibatis.type.BlobTypeHandler},			   #{fileName, jdbcType=VARCHAR})	</insert>		<delete id="deletePhotoByPhotoId">		DELETE FROM PHOTO_TBL		      WHERE PHOTO_ID = #{photoId, jdbcType=VARCHAR}	</delete>		<update id="updatephotoData" >		UPDATE PHOTO_TBL 		   SET PHOTO_DATA = #{photoData, javaType=byte[], jdbcType=BLOB, typeHandler=org.apache.ibatis.type.BlobTypeHandler},		       FILE_NAME = #{fileName, jdbcType=VARCHAR}		 WHERE PHOTO_ID = #{photoId, jdbcType=VARCHAR}	</update>			<select id="getPhotoEntityByPhotoId" resultMap="photoMapper_resultMap_photoEntity">		SELECT PHOTO_ID,		       PHOTO_DATA,		       FILE_NAME		  FROM PHOTO_TBL		 WHERE PHOTO_ID = #{photoId, jdbcType=VARCHAR}	</select></mapper>
 
1.7 spring配置文件

    需要Spring配置文件添加一个org.springframework.web.multipart.commons.CommonsMultipartResolver的bean的声明。

Xml代码 复制代码  收藏代码
  1. <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">  
  2.     <property name="maxUploadSize" value="1073741824" />  
  3. </bean>  
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">	<property name="maxUploadSize" value="1073741824" /></bean>
 

 

 

2. 将文件到服务器上

Java代码 复制代码  收藏代码
  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. }  
private static final String uploadFilePath = "d:\\temp_upload_file\\";/** * 新增 - 提交 – 只保存文件到服务器上 */@RequestMapping(value = "addAction.do")public String add_action(ModelMap model, StudentForm form) {try {		MultipartFile uploadFile = form.getStudentPhoto();		String filename = uploadFile.getOriginalFilename();		InputStream is = uploadFile.getInputStream();		// 如果服务器已经存在和上传文件同名的文件,则输出提示信息		File tempFile = new File(uploadFilePath + filename);		if (tempFile.exists()) {			boolean delResult = tempFile.delete();			System.out.println("删除已存在的文件:" + delResult);		}		// 开始保存文件到服务器		if (!filename.equals("")) {			FileOutputStream fos = new FileOutputStream(uploadFilePath + filename);			byte[] buffer = new byte[8192]; // 每次读8K字节			int count = 0;			// 开始读取上传文件的字节,并将其输出到服务端的上传文件输出流中			while ((count = is.read(buffer)) > 0) {				fos.write(buffer, 0, count); // 向服务端文件写入字节流			}			fos.close(); // 关闭FileOutputStream对象			is.close(); // InputStream对象		}	} catch (FileNotFoundException e) {		e.printStackTrace();	} catch (IOException e) {		e.printStackTrace();	}}
 

 

 

3. 将文件上传到数据库中

Java代码 复制代码  收藏代码
  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. }  
/** * 新增 - 提交 – 保存文件到数据库 */@RequestMapping(value = "addAction.do")public String add_action(ModelMap model, StudentForm form) {	InputStream is = form.getStudentPhoto().getInputStream();	byte[] studentPhotoData = new byte[(int) form.getStudentPhoto().getSize()];	is.read(studentPhotoData);	String fileName = form.getStudentPhoto().getOriginalFilename();	PhotoEntity photoEntity = new PhotoEntity();	photoEntity.setPhotoData(studentPhotoData);	photoEntity.setFileName(fileName);	this.photoMapper.createPhoto(photoEntity);}
 

 

 

4.下载文件

       下载文件需要将byte数组还原成文件。

         首先使用mybatis将数据库中的byte数组查出来,指定文件名(包括格式)。然后使用OutputStream将文件输入

 

Java代码 复制代码  收藏代码
  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. }  
@RequestMapping(value = "downPhotoById")public void downPhotoByStudentId(String id, final HttpServletResponse response){	PhotoEntity entity = this.photoMapper.getPhotoEntityByPhotoId(id);	byte[] data = entity.getPhotoData();	String fileName = entity.getFileName()== null ? "照片.png" : entity.getFileName();	fileName = URLEncoder.encode(fileName, "UTF-8");	response.reset();	response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");	response.addHeader("Content-Length", "" + data.length);	response.setContentType("application/octet-stream;charset=UTF-8");	OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());	outputStream.write(data);	outputStream.flush();	outputStream.close();}

 

Html代码 复制代码  收藏代码
  1. <a href="<%=request.getContextPath() %>/downPhotoById.do?id=8000001">下载照片</a>  
<a href="<%=request.getContextPath() %>/downPhotoById.do?id=8000001">下载照片</a>
 

 

 

5. 显示byte图片文件

Java代码 复制代码  收藏代码
  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. }  
@RequestMapping(value = "getPhotoById")public void getPhotoById (String id, final HttpServletResponse response){	PhotoEntity entity = this.photoMapper.getPhotoEntityByPhotoId(id);	byte[] data = entity.getPhotoData();	response.setContentType("image/jpeg");	response.setCharacterEncoding("UTF-8");	OutputStream outputSream = response.getOutputStream();	InputStream in = new ByteArrayInputStream(data);	int len = 0;	byte[] buf = new byte[1024];	while ((len = in.read(buf, 0, 1024)) != -1) {		outputSream.write(buf, 0, len);	}	outputSream.close();}
 
Html代码 复制代码  收藏代码
  1. <img src="<%=request.getContextPath() %>/getPhotoById.do?id=8000001"/>  
<img src="<%=request.getContextPath() %>/getPhotoById.do?id=8000001"/>
 

 

 

6. 按长宽等比例缩放图片

Java代码 复制代码  收藏代码
  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. }  
@RequestMapping(value = "getPhotoId")public void getPhotoById (String id, int width, int height, final HttpServletResponse response){	PhotoEntity entity = this.photoMapper.getPhotoEntityByPhotoId(id);	byte[] data = entity.getPhotoData();	if (width != 0 && height != 0) {		data = scaleImage(data, width, height);	}	response.setContentType("image/jpeg");	response.setCharacterEncoding("UTF-8");	OutputStream outputSream = response.getOutputStream();	InputStream in = new ByteArrayInputStream(data);	int len = 0;	byte[] buf = new byte[1024];	while ((len = in.read(buf, 0, 1024)) != -1) {		outputSream.write(buf, 0, len);	}	outputSream.close();}public static byte[] scaleImage(byte[] data, int width, int height) throws IOException {	BufferedImage buffered_oldImage = ImageIO.read(new ByteArrayInputStream(data));	int imageOldWidth = buffered_oldImage.getWidth();	int imageOldHeight = buffered_oldImage.getHeight();	double scale_x = (double) width / imageOldWidth;	double scale_y = (double) height / imageOldHeight;	double scale_xy = Math.min(scale_x, scale_y);	int imageNewWidth = (int) (imageOldWidth * scale_xy);	int imageNewHeight = (int) (imageOldHeight * scale_xy);	BufferedImage buffered_newImage = new BufferedImage(imageNewWidth, imageNewHeight, BufferedImage.TYPE_INT_RGB);	buffered_newImage.getGraphics().drawImage(buffered_oldImage.getScaledInstance(imageNewWidth, imageNewHeight, BufferedImage.SCALE_SMOOTH), 0, 0, null);	buffered_newImage.getGraphics().dispose();	ByteArrayOutputStream outPutStream = new ByteArrayOutputStream();	ImageIO.write(buffered_newImage, "jpeg", outPutStream);	return outPutStream.toByteArray();}
 
Html代码 复制代码  收藏代码
  1. <img src="<%=request.getContextPath() %>/getPhotoById.do?id=8000001&width=300&height=300"/>  
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值