您的位置:首页 > 编程语言 > Java开发

myBatis + SpringMVC上传、下载文件

2014-03-27 09:05 393 查看
摘自: http://limingnihao.iteye.com/blog/1069503
环境: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代码

<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代码

/**

* 新增 - 提交

*/

@RequestMapping(value = "addAction.do")

public String add_action(ModelMap model, StudentForm form) {

}

1.3 StudentForm类

Java代码

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代码

CREATE TABLE PHOTO_TBL

(

PHOTO_ID VARCHAR(100) PRIMARY KEY,

PHOTO_DATA LONGBLOB,

FILE_NAME VARCHAR(10)

);

1.5 PhotoMapper接口

Java代码

@Repository

@Transactional

public 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代码

<?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代码

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

<property name="maxUploadSize" value="1073741824" />

</bean>

2. 将文件到服务器上

Java代码

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代码

/**

* 新增 - 提交 – 保存文件到数据库

*/

@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代码

@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代码

<a href="<%=request.getContextPath() %>/downPhotoById.do?id=8000001">下载照片</a>

5. 显示byte图片文件

Java代码

@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代码

<img src="<%=request.getContextPath() %>/getPhotoById.do?id=8000001"/>

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

Java代码

@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代码

<img src="<%=request.getContextPath() %>/getPhotoById.do?id=8000001&width=300&height=300"/>

7

0


分享到:

dwr学习 之 一、dwr+spring的简单集成 | MyBatis学习 之 四、MyBatis配置文件

2011-06-03 13:58

浏览 11476

评论(6)

分类:编程语言

相关推荐

评论

6 楼 zqb666kkk 2013-12-23
PhotoEntity 呢?

5 楼 zqb666kkk 2013-12-23
photoEntity.setPhotoData(studentPhotoData);

你这句话 有问题吧

实体类里 是 private MultipartFile studentPhoto;

MultipartFile 类型的
set的时候byte[] 类型
类型不符合 编译都通不过的

4 楼 eye_dxj 2013-10-30
outputStream.flush();

3 楼 ddnzero 2013-05-21
PhotoMapper.xml文件 这个正需要啊 感谢~

2 楼 我是菜鸟1号 2013-03-29
貌似没看到 PhotoEntity 这个类吧...

1 楼 幸福人生 2011-09-23
很好,代码直接拷贝就可以,支持一下!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: