zoukankan      html  css  js  c++  java
  • 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表单写法

    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>  
     

    1.2 action方法

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

    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. }  
     

    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. );  
     

    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. }  
     

    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>  
     

    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>  
     

    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. }  
     

    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. }  
     

    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. }  
    Html代码  
    1. <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. }  
     
    Html代码  
    1. <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. }  
     
    Html代码  
    1. <img src="<%=request.getContextPath() %>/getPhotoById.do?id=8000001&width=300&height=300"/>  
     
    7 
    0 
    分享到:  
    评论
    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  
    很好,代码直接拷贝就可以,支持一下!
  • 相关阅读:
    盒子模型
    css基本选择器
    css样式写法<link和style>
    将博客搬至CSDN
    Mac AndroidStudio 快捷键整理搜藏
    Android 图片黑白显示 自定义饱和度
    android studio 将包含jar包的项目打包成jar包
    JNI方法命名和方法签名
    Mac 下配置NDK/JNI开发环境,并运行简单demo
    Installation failed with message Failed to establish session报错
  • 原文地址:https://www.cnblogs.com/wuyifu/p/3627516.html
Copyright © 2011-2022 走看看