myBatis + SpringMVC上传、下载文件
摘自: 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表单写法
- <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方法
- /**
- * 新增 - 提交
- */
- @RequestMapping(value = "addAction.do")
- public String add_action(ModelMap model, StudentForm form) {
- }
1.3 StudentForm类
- 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
- CREATE TABLE PHOTO_TBL
- (
- PHOTO_ID VARCHAR(100) PRIMARY KEY,
- PHOTO_DATA LONGBLOB,
- FILE_NAME VARCHAR(10)
- );
1.5 PhotoMapper接口
- @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 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的声明。
- <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
- <property name="maxUploadSize" value="1073741824" />
- </bean>
2. 将文件到服务器上
- 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. 将文件上传到数据库中
- /**
- * 新增 - 提交 – 保存文件到数据库
- */
- @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将文件输入
- @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();
- }
- <a href="<%=request.getContextPath() %>/downPhotoById.do?id=8000001">下载照片</a>
5. 显示byte图片文件
- @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();
- }
- <img src="<%=request.getContextPath() %>/getPhotoById.do?id=8000001"/>
6. 按长宽等比例缩放图片
- @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();
- }
- <img src="<%=request.getContextPath() %>/getPhotoById.do?id=8000001&width=300&height=300"/>
顶
踩
评论
你这句话 有问题吧
实体类里 是 private MultipartFile studentPhoto;
MultipartFile 类型的
set的时候byte[] 类型
类型不符合 编译都通不过的
myBatis + SpringMVC上传、下载文件的更多相关文章
- SpringMVC 上传下载 异常处理
SpringMVC 上传下载 异常处理 上一章节对SpringMVC的表单验证进行了详细的介绍,本章节介绍SpringMVC文件的上传和下载(重点),国际化以及异常处理问题.这也是SpringMVC系 ...
- rz和sz上传下载文件工具lrzsz
######################### rz和sz上传下载文件工具lrzsz ####################################################### ...
- linux上很方便的上传下载文件工具rz和sz
linux上很方便的上传下载文件工具rz和sz(本文适合linux入门的朋友) ##########################################################&l ...
- shell通过ftp实现上传/下载文件
直接代码,shell文件名为testFtptool.sh: #!/bin/bash ########################################################## ...
- SpringMVC上传压缩文件,解压文件,并检测上传文件中是否有index.html
SpringMVC上传压缩文件,解压文件,并检测上传文件中是否有index.html 说明: 1.环境:SpringMVC+Spring+Tomcat7+JDK1.7 2.支持 zip和rar格式的压 ...
- SFTP远程连接服务器上传下载文件-qt4.8.0-vs2010编译器-项目实例
本项目仅测试远程连接服务器,支持上传,下载文件,更多功能开发请看API自行开发. 环境:win7系统,Qt4.8.0版本,vs2010编译器 qt4.8.0-vs2010编译器项目实例下载地址:CSD ...
- linux下常用FTP命令 上传下载文件【转】
1. 连接ftp服务器 格式:ftp [hostname| ip-address]a)在linux命令行下输入: ftp 192.168.1.1 b)服务器询问你用户名和密码,分别输入用户名和相应密码 ...
- C#实现http协议支持上传下载文件的GET、POST请求
C#实现http协议支持上传下载文件的GET.POST请求using System; using System.Collections.Generic; using System.Text; usin ...
- HttpClient上传下载文件
HttpClient上传下载文件 java HttpClient Maven依赖 <dependency> <groupId>org.apache.httpcomponents ...
- 初级版python登录验证,上传下载文件加MD5文件校验
服务器端程序 import socket import json import struct import hashlib import os def md5_code(usr, pwd): ret ...
随机推荐
- 20169211《Linux内核原理与分析》第一周作业
本科期间,学校开设过linux相关的课程,当时的学习方式主要以课堂听授为主.虽然老师也提供了相关的学习教材跟参考材料,但是整体学下来感觉收获并不是太大,现在回想起来,主要还是由于自己课下没 ...
- Python网络模块Paramiko基本使用
一.Paramiko简介 首先来看谁创造了paramiko,是一个名叫Jeff Forcier创建了paramiko项目.项目主页:http://www.paramiko.org,可以去看上面有很多相 ...
- iOS 9音频应用播放音频之播放控制暂停停止前进后退的设置
iOS 9音频应用播放音频之播放控制暂停停止前进后退的设置 ios9音频应用播放控制 在“iOS 9音频应用播放音频之ios9音频基本功能”一文可以看到AVAudioPlayer类有很多的属性以及方法 ...
- Google的代码高亮-code-prettify
前不久发现,在wordpress中贴代码的时候,发现code标签并没有意料中的好使用,在贴代码的时候没有高亮真的是一件无法忍受的事情. 正巧,两周前听过同事Eason的一个关于Markdown的分享, ...
- FastReport.Net使用:[15]富文本控件使用
富文本(Rich Text)控件用于显示Rtf格式的文本. 认识富文本编辑窗体 1.下图就是富文本的编辑窗体,乍一看就像Word一样,不过功能没有Word强大了.具体功能就不一一介绍了,用个Word的 ...
- 【UOJ #112】【APIO 2015】Palembang Bridges
http://uoj.ac/problem/112 先扣掉在同一侧的情况. 当\(k=1\)时,桥建在所有位置的中位数. 当\(k=2\)时,对于每个居民\((S_i,T_i)\),这个居民只会走离\ ...
- hdu1028 Ignatius and the Princess III(生成函数整理占坑)upd 已咕
先咕着 ---------------2018 5 22---------------------- 题解 生成函数处理整数拆分 code #include<cstdio> #includ ...
- BZOJ1018 堵塞的交通(线段树)
题目很好明白,然后实现很神奇.首先如果考虑并查集的话,对于删边和加边操作我们无法同时进行.然后暴力分块的话,复杂度是O(n sqrt n) ,不是很优.于是看了题解,发现了线段树的神奇用途. 我们维护 ...
- hibernate核心及常用技术
一.hibernate介绍 1.hibernate概述 hibernate是轻量级Java EE持久层解决方案,管理java类到数据库表的映射(ORM:对象关系型数据映射),并提供数据查询获取的方法. ...
- [NC13A]反蝴蝶效应/[SPOJ-NPC2014D]General Joke
[NC13A]反蝴蝶效应/[SPOJ-NPC2014D]General Joke 题目大意: 按顺序访问\(A_{1\sim n}(n\le10^5)\),经过\(A_i\)时身上必须有\(A_i\) ...