6、SpringMVC实现文件上传下载

SpringMVC-servlet.xml

使用springMVC来处理文件上传和下载须要添加以下的配置文件,并且id是固定的
能够到org.springframework.web.servlet.DispatcherServlet的源码文件下查看
CommonsMultipartResolver提供三个属性设置,能够跳转到源码开头的注释查看
SpringMVC-servlet.xml中添加如下:html

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
       <property name="DefaultEncoding" value="UTF-8" />
       <property name="MaxUploadSize" value="1048576" />
       <property name="MaxInMemorySize" value="4096"/>  
</bean>

CommonsMultipartResolver源码注释部分片断:java

/**
 * Servlet-based {@link MultipartResolver} implementation for
 * <a href="http://commons.apache.org/proper/commons-fileupload">Apache Commons FileUpload</a>
 * 1.2 or above.
 *
 * <p>Provides "maxUploadSize", "maxInMemorySize" and "defaultEncoding" settings as
 * bean properties (inherited from {@link CommonsFileUploadSupport}). See corresponding
 * ServletFileUpload / DiskFileItemFactory properties ("sizeMax", "sizeThreshold",
 * "headerEncoding") for details in terms of defaults and accepted values.
 *
 * <p>Saves temporary files to the servlet container's temporary directory.
 * Needs to be initialized <i>either</i> by an application context <i>or</i>
 * via the constructor that takes a ServletContext (for standalone usage).
 */
public class CommonsMultipartResolver extends CommonsFileUploadSupport{}

springmvc的DispatcherServlet部分源码web

/** Well-known name for the MultipartResolver object in the bean factory for this namespace. */
    public static final String MULTIPART_RESOLVER_BEAN_NAME = "multipartResolver";

    /** Well-known name for the LocaleResolver object in the bean factory for this namespace. */
    public static final String LOCALE_RESOLVER_BEAN_NAME = "localeResolver";

    /** Well-known name for the ThemeResolver object in the bean factory for this namespace. */
    public static final String THEME_RESOLVER_BEAN_NAME = "themeResolver";

    /**
     * Well-known name for the HandlerMapping object in the bean factory for this namespace.
     * Only used when "detectAllHandlerMappings" is turned off.
     * @see #setDetectAllHandlerMappings
     */
    public static final String HANDLER_MAPPING_BEAN_NAME = "handlerMapping";

    /**
     * Well-known name for the HandlerAdapter object in the bean factory for this namespace.
     * Only used when "detectAllHandlerAdapters" is turned off.
     * @see #setDetectAllHandlerAdapters
     */
    public static final String HANDLER_ADAPTER_BEAN_NAME = "handlerAdapter";

    /**
     * Well-known name for the HandlerExceptionResolver object in the bean factory for this namespace.
     * Only used when "detectAllHandlerExceptionResolvers" is turned off.
     * @see #setDetectAllHandlerExceptionResolvers
     */
    public static final String HANDLER_EXCEPTION_RESOLVER_BEAN_NAME = "handlerExceptionResolver";

    /**
     * Well-known name for the RequestToViewNameTranslator object in the bean factory for this namespace.
     */
    public static final String REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME = "viewNameTranslator";

    /**
     * Well-known name for the ViewResolver object in the bean factory for this namespace.
     * Only used when "detectAllViewResolvers" is turned off.
     * @see #setDetectAllViewResolvers
     */
    public static final String VIEW_RESOLVER_BEAN_NAME = "viewResolver";

    /**
     * Well-known name for the FlashMapManager object in the bean factory for this namespace.
     */
    public static final String FLASH_MAP_MANAGER_BEAN_NAME = "flashMapManager";

文件上传逻辑java文件: UploadController.java

package main.java.com.smart.web;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;


@Controller
public class UploadController {

    @Resource
    HttpServletRequest request;

    /**
     * @return  返回相对路径RelativePath
     */
    public String RelPath() {
        String path = request.getContextPath();
        return request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    }

    /**
     * @return  返回服务器目录的真实路径
     */
    public String RealPath() {
        return request.getSession().getServletContext().getRealPath("/");
    }

    /**
     *  单文件上传
     * 
     * @param imageFile
     * @param request
     * @return
     */
    @RequestMapping("/singleUpload")    
    public String singleUpload(@RequestParam("imageFile") MultipartFile imageFile, HttpServletRequest request){//, 

        String filename = imageFile.getOriginalFilename();

        File dir = new File(RealPath()+"upload/");//1.新建一个文件夹对象
        if(!dir.exists()){              //2.检查路径下upload文件夹是否存在
            dir.mkdirs();
        }

        System.out.println("文件上传到:"+RelPath()+"upload/"+ filename);

        File targetFile = new File(RealPath()+"upload/"+ filename);//3.在文件夹下新建一个filename文件的文件对象,此处新建文件应该新建在确切的物理路径下

        if(!targetFile.exists()){//4.判断真实路径下是否存在filename文件
            try {
                targetFile.createNewFile();//5.在真实路径下建立filename空文件
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        try {
            imageFile.transferTo(targetFile);//6.复制文件到真实路径下
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("真实路径:"+RealPath()+"upload/");
        System.out.println("相对路径:"+RelPath()+"upload/");

        return "redirect:"+RelPath()+"upload/"+filename;            //非安全目录下使用(可用)
        //return "redirect:"+RealPath()+"upload/"+filename;                 //重定向到真实地址(不可用)
        //return "redirect:http://localhost:8080/SpringMvcTest/upload/"+filename;
    }

    /**
     * 多文件上传
     * @param request
     * @return
     */
    @RequestMapping("/multiUpload")
    public String multiUpload(HttpServletRequest request){

        MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest)request;//一、将请求进行转义

        Map<String, MultipartFile> files = multipartHttpServletRequest.getFileMap();//二、获取同一表单提交过来的全部文件

        //三、在真实路径建立文件
        File dir = new File(RealPath()+"upload/");
        if(!dir.exists()) {
            dir.mkdirs();
        }

        List<String> fileList = new ArrayList<String>();//四、将上传的文件的相对地址保存在一个列表中(客户端只能请求服务器的相对地址)

        for(MultipartFile file : files.values()) {  //五、在服务器的绝对地址下新建文件,并将上传的文件复制过去,将相对路径保存进List列表中,服务器的相对路径和绝对路径是相互映射的,客户端只能请求相对路径
            File targetFile = new File(RealPath()+"upload/" + file.getOriginalFilename()); 
            if(!targetFile.exists()) {
                try {
                    targetFile.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                try {
                    file.transferTo(targetFile);
                    fileList.add(RelPath()+"upload/"+file.getOriginalFilename());
                } catch (IllegalStateException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }else{
                fileList.add(RelPath()+"upload/"+file.getOriginalFilename());//文件若是存在直接访问
            }

        }
        System.out.println(fileList);
        request.setAttribute("files", fileList);

        return "/WEB-INF/jsp/multiUploadResult.jsp";    
    }
}

singleUpload.jsp(WEB-INF安全目录下)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<base href="<%=basePath%>">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>单文件 上传</title>
</head>
<body>
    <div style="margin: 0 auto;margin-top: 100px;">
        <form action="singleUpload.html" method="post" enctype="multipart/form-data">
            <p>
                <span>文件:</span>
                <input type="file" name="imageFile">
            </p>
            <p>
                <input type="submit">
            </p>
        </form>
    </div>
</body>
</html>

multiUpload.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
    <%
        String path = request.getContextPath();
        String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <base href="<%=basePath%>">
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>多文件上传</title>
    </head>
    <body>
        <div style="margin: 0 auto;margin-top: 100px; ">

            <form action="multiUpload.html" method="post" enctype="multipart/form-data">
                <p>
                    <span>文件1:</span>
                    <input type="file" name="imageFile1">
                </p>
                <p>
                    <span>文件2:</span>
                    <input type="file" name="imageFile2">
                </p>            
                <p>
                    <input type="submit">
                </p>
            </form>

        </div>
    </body>
    </html>

multiUploadResult.jsp

<%@page import="java.util.List" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<base href="<%=basePath%>">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>多文件 上传结果</title>
</head>
<body>

    <div style="margin: 0 auto;margin-top: 100px; ">
        <p>${files}</p>
        <% 
            List<String> fileList = (List)request.getAttribute("files");
            for(String url : fileList){
        %>
            <p><%=url %></p><br>
            <a href="<%=url %>">
                <img alt="" src="<%=url %>">
            </a>

        <% 
            }
        %>
    </div>

</body>
</html>

文件下载

package main.java.com.smart.web;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class DownloadController {

    @Resource
    HttpServletRequest request;

    @Resource
    HttpServletResponse response;

    @RequestMapping("/download")
    public String download(@RequestParam String fileName){

        response.setContentType("text/html;charset=utf-8");//1.设置响应的文件类型和文件编码

        try {
            request.setCharacterEncoding("UTF-8");//2.确保请求的编码类型为UTF-8,否则文件下载后有可能由于类型不一致出现乱码
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;

        String ctxPath = request.getSession().getServletContext().getRealPath("/")+"upload/";
        String downLoadPath = ctxPath + fileName;
        System.out.println(downLoadPath);

        try{
            long fileLength = new File(downLoadPath).length();

            //3.设置响应头文件内容,文件类型、弹出下载对话框、文件大小
            response.setContentType("application/x-msdownload");
            response.setHeader("Content-disposition", "attachment; filename=" + new String(fileName.getBytes("utf-8"), "ISO8859-1"));
            response.setHeader("Content-Length", String.valueOf(fileLength));

            bis = new BufferedInputStream(new FileInputStream(downLoadPath));//4.新建一个输入流缓存对象,并将文件输入流对象传递进去,将文件路径传递进文件输入流对象中,这是一个逐步处理的过程
            bos = new BufferedOutputStream(response.getOutputStream());//5.新建一个输出流缓存对象,将服务器响应输出流对象至于其中
            byte[] buff = new byte[2048];//6.新建一个缓存
            int bytesRead;              //7.内容字节总数
            while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {//8.输入到到buff缓存中,当文件为空是read()会return -1,不然返回读取的字节总数
                bos.write(buff, 0, bytesRead);//9.将buff的字节写到响应体的输出流中,输出流持续输出到客户端
            }

        } catch(Exception e) {
            e.printStackTrace();
        } finally {
            if (bis != null)
                try {
                    bis.close();//10.关闭缓存输入流对象
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            if (bos != null)
                try {
                    bos.close();//10.关闭缓存输出流对象
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
        }       
        return null;    
    }
}

请求方式举栗

<a href="download.html?fileName='文件名'">下载文件 </a>

多文件上传Web截图示例:

这里写图片描述


原创+装载,若有侵权请指出立马处理spring