Spring 文件上传

获取文件流的方法,已经在专题的“(二)Spring- RestController 请求参数详解” 中说过了,大家可以去找之前的获取方式。 本篇主要讲的是文件上传的处理和保存。中间件使用的是tomcat。

1. 文件上传配置

文件上传需要增加一个依赖包

    <!--flieupload-->
    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.3</version>
    </dependency>

在spring 的配置文件中,配置图片处理的bin文件

    <!-- 上传文件拦截,设置最大上传文件大小   10M=10*1024*1024(B)=10485760 bytes -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="10485760" />
    </bean>

2. 文件上传处理的方法

现在共有2个方法,大家还可以根据自己需求,把生成文件名的方法和生成缩略图大小的方法抽离出来,这里是示例,就不写那么复杂了。

  • 1单文件上传
  • 2单文件上传并自动生成缩略图


public class FilesService {

   //文件相对Tomcat路径,相对tomcat设置,暂时弃用
   //public static final String FILE_PATH = "../user_res/upload/plantAssistant/";

   //文件相对网站路径
   public static final String FILE_PATH = "WEB-INF/upload";

       //单文件上传
       public static FilesResp uploadFile(MultipartFile file, HttpServletRequest request) throws IOException {
           //获取上传的路径
           String realpath = request.getSession().getServletContext().getRealPath(FILE_PATH);
           //获取文件名
           String fileName = file.getOriginalFilename();
           //上传文件
           File tempFile = new File(realpath, new Date().getTime() + "_" + String.valueOf(fileName));
           if (!tempFile.getParentFile().exists()) {
               tempFile.getParentFile().mkdir();
           }
           if (!tempFile.exists()) {
               tempFile.createNewFile();
           }
           file.transferTo(tempFile);

           //处理返回值
           FilesResp fileResp = new FilesResp(tempFile.getName(),getDomain(request));
           return fileResp;
       }

       //单文件上传,并生成缩略图
       public static FilesResp uploadFileAndThum(MultipartFile file, HttpServletRequest request) throws IOException{

           String realpath = request.getSession().getServletContext().getRealPath(FILE_PATH);
           //上传图片
           FilesResp fileResp = uploadFile(file,request);

           //生成缩略图
           File srcImageFile = new File(realpath,fileResp.getFileName());
           try {
               makeSmallImage(srcImageFile,realpath + "/thum_"+fileResp.getFileName());
           }catch (Exception e){
               System.out.println("生成缩略图出错");
           }
           return new FilesResp(fileResp.getFileName(),"thum_"+fileResp.getFileName(),getDomain(request));

       }


       public static File getFile(String fileName,HttpServletRequest request) {
           String realpath = request.getSession().getServletContext().getRealPath(FILE_PATH);
           return new File(realpath, fileName);
       }

       /**
            * 生成缩略图
            * @param srcImageFile 源图片文件的File实例      File file = new File("文件名");
            * @param dstImageFileName 待生成的缩略图片完整路径(生成的格式为:image/jpeg);
            * @throws Exception
            */
           public static void makeSmallImage(File srcImageFile,String dstImageFileName) throws Exception {
               FileOutputStream fileOutputStream = null;
               JPEGImageEncoder encoder = null;
               BufferedImage tagImage = null;
               Image srcImage = null;
               try{
                   srcImage = ImageIO.read(srcImageFile);
                   int srcWidth = srcImage.getWidth(null);//原图片宽度
                   int srcHeight = srcImage.getHeight(null);//原图片高度
                   int dstMaxSize = 120;//目标缩略图的最大宽度/高度,宽度与高度将按比例缩写
                   int dstWidth = srcWidth;//缩略图宽度
                   int dstHeight = srcHeight;//缩略图高度
                   float scale = 0;
                   //计算缩略图的宽和高
                   if(srcWidth>dstMaxSize){
                       dstWidth = dstMaxSize;
                       scale = (float)srcWidth/(float)dstMaxSize;
                       dstHeight = Math.round((float)srcHeight/scale);
                   }
                   srcHeight = dstHeight;
                   if(srcHeight>dstMaxSize){
                       dstHeight = dstMaxSize;
                       scale = (float)srcHeight/(float)dstMaxSize;
                       dstWidth = Math.round((float)dstWidth/scale);
                   }
                   //生成缩略图
                   tagImage = new BufferedImage(dstWidth,dstHeight,BufferedImage.TYPE_INT_RGB);
                   tagImage.getGraphics().drawImage(srcImage,0,0,dstWidth,dstHeight,null);
                   fileOutputStream = new FileOutputStream(dstImageFileName);
                   encoder = JPEGCodec.createJPEGEncoder(fileOutputStream);
                   encoder.encode(tagImage);
                   fileOutputStream.close();
                   fileOutputStream = null;
               }finally{
                   if(fileOutputStream!=null){
                       try{
                           fileOutputStream.close();
                       }catch(Exception e){
                       }
                       fileOutputStream = null;
                   }
                   encoder = null;
                   tagImage = null;
                   srcImage = null;
                   System.gc();
               }
           }

           //获取域名
           private static String getDomain(HttpServletRequest request){
               StringBuffer url = request.getRequestURL();
               return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString();
           }
}


3方法的返回类型 FilesResp

这个类型是我自己写的,大家也可以不用他,自己去定义,既然例子中有,我就把返回类型贴出来,里面的返回值生成了各种常用的标签,因为后面想搭一个自己的图库



public class Resp {

    public static Resp succeedResp(Object data){
        Resp resp = new Resp();
        resp.setStatus(1);
        resp.setData(data);
        resp.setMsg("返回成功");
        return resp;

    }
    public static Resp succeedRespWithMsgAndData(String msg,Object data){
        Resp resp = new Resp();
        resp.setStatus(1);
        resp.setData(data);
        resp.setMsg(msg);
        return resp;

    }
    public static Resp succeedRespWithMsg(String msg){
        return succeedRespWithMsgAndData(msg,null);
    }
    public static Resp failureResp(String msg){
        Resp resp = new Resp();
        resp.setStatus(0);
        resp.setMsg(msg);
        return resp;
    }

    private int status;
    private String msg;
    protected Object data;

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}

package com.jumppo.plantassistant.dao.model.response;

import org.springframework.http.HttpRequest;

import javax.servlet.http.HttpServletRequest;

/**
 * Created by zteliuyw on 15/7/13.
 */
public class FilesResp  {

    private String fileName;
    private String downloadUrl;
    private String previewUrl;
    private String htmlTag;
    private String aTag;
    private String mdTag;

    private String thum_fileName;
    private String thum_downloadUrl;
    private String thum_previewUrl;
    private String thum_htmlTag;
    private String thum_aTag;
    private String thum_mdTag;

    public  FilesResp(String fileName){

        this.fileName = fileName;
        this.downloadUrl = "/files/download?fileName=" + fileName;
        this.previewUrl =   "/files/preview?fileName=" + fileName;
        this.htmlTag = "<img src=\" "+ this.previewUrl +" \" />";
        this.aTag = "<a href=\"图片超链接地址\"><img src=\" "+ this.previewUrl +" \" /><a>";
        this.mdTag = "![图片文字:]("+  this.previewUrl + ")";
    }
    public FilesResp(String fileName,String domain){

        this.fileName = fileName;
        this.downloadUrl = domain + "/files/download?fileName=" + fileName;
        this.previewUrl = domain + "/files/preview?fileName=" + fileName;
        this.htmlTag = "<img src=' "+ this.previewUrl +" ' />";
        this.aTag = "<a href='图片超链接地址'> <img src='"+ this.previewUrl +" ' /><a>";
        this.mdTag = "![图片文字:]("+  this.previewUrl + ")";
    }
    public FilesResp(String fileName,String thumFileName,String domain){

        this(fileName, domain);
        this.thum_fileName = thumFileName;
        this.thum_downloadUrl = domain + "/files/download?fileName=" + thumFileName;
        this.thum_previewUrl = domain + "/files/preview?fileName=" + thumFileName;
        this.thum_htmlTag = "<img src=' "+ this.thum_previewUrl +" ' />";
        this.thum_aTag = "<a href='图片超链接地址'> <img src='"+ this.thum_previewUrl +" ' /><a>";
        this.thum_mdTag = "![图片文字:]("+  this.thum_previewUrl + ")";

    }

    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public String getDownloadUrl() {
        return downloadUrl;
    }

    public void setDownloadUrl(String downloadUrl) {
        this.downloadUrl = downloadUrl;
    }

    public String getPreviewUrl() {
        return previewUrl;
    }

    public void setPreviewUrl(String previewUrl) {
        this.previewUrl = previewUrl;
    }

    public String getHtmlTag() {
        return htmlTag;
    }

    public void setHtmlTag(String htmlTag) {
        this.htmlTag = htmlTag;
    }

    public String getaTag() {
        return aTag;
    }

    public void setaTag(String aTag) {
        this.aTag = aTag;
    }

    public String getMdTag() {
        return mdTag;
    }

    public void setMdTag(String mdTag) {
        this.mdTag = mdTag;
    }

    public String getThum_fileName() {
        return thum_fileName;
    }

    public void setThum_fileName(String thum_fileName) {
        this.thum_fileName = thum_fileName;
    }

    public String getThum_downloadUrl() {
        return thum_downloadUrl;
    }

    public void setThum_downloadUrl(String thum_downloadUrl) {
        this.thum_downloadUrl = thum_downloadUrl;
    }

    public String getThum_previewUrl() {
        return thum_previewUrl;
    }

    public void setThum_previewUrl(String thum_previewUrl) {
        this.thum_previewUrl = thum_previewUrl;
    }

    public String getThum_htmlTag() {
        return thum_htmlTag;
    }

    public void setThum_htmlTag(String thum_htmlTag) {
        this.thum_htmlTag = thum_htmlTag;
    }

    public String getThum_aTag() {
        return thum_aTag;
    }

    public void setThum_aTag(String thum_aTag) {
        this.thum_aTag = thum_aTag;
    }

    public String getThum_mdTag() {
        return thum_mdTag;
    }

    public void setThum_mdTag(String thum_mdTag) {
        this.thum_mdTag = thum_mdTag;
    }
}



4 最后是接受文件上传的控制器

有几点和大家说明下:

  • 1:单个文件上传,路由参数这样写: @RequestParam(“file”) MultipartFile file,那么文件在表单中的name属性就必须是flie(不是文件名,是文件对应的name属性),这里是简单的写法,相当于 MultipartFile file = ((MultipartHttpServletRequest) request).getFile(“file”);

  • 2:多个文件上传,参数@RequestParam(“files”) MultipartFile[] files
  • 3:下载和预览,这两个方法其实只相差一个地方,response.setHeader(“Content-Disposition”, “attachment; filename=” + fileName);,这段话会通知浏览器以下载的方式处理流


@RestController
@RequestMapping("/files")
public class FliesController {



        @RequestMapping("upload")
        public Resp upload(HttpServletRequest request,
                           HttpServletResponse response, @RequestParam("file") MultipartFile file){

            System.out.println("files/upload");
            try {
                //MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
                FilesResp filesResp = FilesService.uploadFile(file, request);
                return Resp.succeedResp(filesResp);
            }
            catch (Exception e){
                e.printStackTrace();
            }

            return Resp.failureResp("图片上传失败");
        }

        @RequestMapping("uploadFileAndThum")
        public Resp uploadFileAndThum(HttpServletRequest request,
                           HttpServletResponse response, @RequestParam("file") MultipartFile file){

            System.out.println("files/upload");
            try {
                //MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
                FilesResp filesResp = FilesService.uploadFileAndThum(file, request);
                return Resp.succeedResp(filesResp);
            }
            catch (Exception e){
                e.printStackTrace();
            }

            return Resp.failureResp("图片上传失败");
        }


    @RequestMapping("batchUpload")
    public Resp batchUpload(HttpServletRequest request,
                       HttpServletResponse response,
                       @RequestParam("files") MultipartFile[] files) throws IOException {
        List<FilesResp> list = new ArrayList<FilesResp>();
        try {
            for (MultipartFile file :files) {
                FilesResp flesResp = FilesService.uploadFile(file, request);
                list.add(flesResp);
//                System.out.println("filePath:" + filePath);
            }
            return Resp.succeedResp(list);
        }
        catch (Exception e){
            e.printStackTrace();
        }
        return  Resp.failureResp("文件上传失败");
    }

    @RequestMapping("download")
    public void download(String fileName, HttpServletResponse response,HttpServletRequest request) throws IOException {
        OutputStream os = response.getOutputStream();
        try {
            response.reset();
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
            response.setContentType("image/jpeg; charset=utf-8");
            os.write(FileUtils.readFileToByteArray(FilesService.getFile(fileName,request)));
            os.flush();
        } finally {
            if (os != null) {
                os.close();
            }
        }
    }
    @RequestMapping("preview")
    public void preview(String fileName, HttpServletResponse response,HttpServletRequest request) throws IOException {
        OutputStream os = response.getOutputStream();
        try {
            response.reset();
//            response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
            response.setContentType("image/jpeg; charset=utf-8");
            os.write(FileUtils.readFileToByteArray(FilesService.getFile(fileName,request)));
            os.flush();
        } finally {
            if (os != null) {
                os.close();
            }
        }
    }
}

返回的json例子

    {
      "status": 1,
      "msg": "返回成功",
      "data": {
        "fileName": "1436776126050_EEFC7812-B34E-43B1-9DCE-1CA965EE20B0.png",
        "downloadUrl": "http://localhost:8070/files/download?fileName=1436776126050_EEFC7812-B34E-43B1-9DCE-1CA965EE20B0.png",
        "previewUrl": "http://localhost:8070/files/preview?fileName=1436776126050_EEFC7812-B34E-43B1-9DCE-1CA965EE20B0.png",
        "htmlTag": "<img src=' http://localhost:8070/files/preview?fileName=1436776126050_EEFC7812-B34E-43B1-9DCE-1CA965EE20B0.png ' />",
        "aTag": "<a href='图片超链接地址'> <img src='http://localhost:8070/files/preview?fileName=1436776126050_EEFC7812-B34E-43B1-9DCE-1CA965EE20B0.png ' /><a>",
        "mdTag": "![图片文字:](http://localhost:8070/files/preview?fileName=1436776126050_EEFC7812-B34E-43B1-9DCE-1CA965EE20B0.png)",
        "thum_fileName": "thum_1436776126050_EEFC7812-B34E-43B1-9DCE-1CA965EE20B0.png",
        "thum_downloadUrl": "http://localhost:8070/files/download?fileName=thum_1436776126050_EEFC7812-B34E-43B1-9DCE-1CA965EE20B0.png",
        "thum_previewUrl": "http://localhost:8070/files/preview?fileName=thum_1436776126050_EEFC7812-B34E-43B1-9DCE-1CA965EE20B0.png",
        "thum_htmlTag": "<img src=' http://localhost:8070/files/preview?fileName=thum_1436776126050_EEFC7812-B34E-43B1-9DCE-1CA965EE20B0.png ' />",
        "thum_aTag": "<a href='图片超链接地址'> <img src='http://localhost:8070/files/preview?fileName=thum_1436776126050_EEFC7812-B34E-43B1-9DCE-1CA965EE20B0.png ' /><a>",
        "thum_mdTag": "![图片文字:](http://localhost:8070/files/preview?fileName=thum_1436776126050_EEFC7812-B34E-43B1-9DCE-1CA965EE20B0.png)"
      }
    }
Loading Disqus comments...
Table of Contents