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

myBatis + SpringMVC上传、下载文件、显示byte图片文件、等比例缩放图片

2016-07-07 11:19 691 查看
来源URL:http://www.cnblogs.com/wuyifu/p/3627516.html

环境: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"/>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: