springmvc4文件上传

一、 上传文件的简单步骤
1.所需jar包
除了spring的jar包外,需要添加commons-fileupload.jar这个jar包

2.修改spring的配置文件
要让springmvc支持文件上传,必须在spring的配置文件中增加下面的配置

<!-- SpringMVC上传文件时,需要配置MultipartResolver处理器 -->  
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">  
    <property name="defaultEncoding" value="UTF-8"/>  
    <!-- 指定所上传文件的总大小,单位字节。注意maxUploadSize属性的限制不是针对单个文件,而是所有文件的容量之和 -->  
    <property name="maxUploadSize" value="1124000"/>  
</bean>

3.前台html表单

<form enctype="multipart/form-data" method="post" action="uploadfile">
    <input type="file" name="file"/>
    <input type="submit" value="submit"/>
</form>

enctype=”multipart/form-data”是必须设置的属性

4.后台实现

@RequestMapping(value = "/uploadfile",method=RequestMethod.POST)
public ModelAndView uploadfileUpload(HttpServletRequest req,HttpServletResponse resp,MultipartFile file) throws Exception {
         ModelAndView mo = new ModelAndView();
        mo.addObject("filename",file.getOriginalFilename());
        mo.addObject ("size", file.getSize()/(1024.0*1024) + "M");
        return mo;
}

这个代码只是简单的返回了上传的文件名字和大小,只是一个示例。实际项目中可操作file对象将上传的文件保存在服务器上。

二、 配置上传文件超过maxUploadSize时跳转的页面
上面再配置文件中配置了上传文件的最大大小,当上传的文件超过最大大小时,spring就会抛出org.springframework.web.multipart.MaxUploadSizeExceededException异常,这个异常是在请求达到controller处理函数之前抛出的,可以通过修改spring配置文件来指定跳转页面,
在spring配置文件中增加如下配置:

<!-- SpringMVC在超出上传文件限制时,会抛出org.springframework.web.multipart.MaxUploadSizeExceededException -->  
<!-- 该异常是SpringMVC在检查上传的文件信息时抛出来的,而且此时还没有进入到Controller方法中 -->  
<bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">  
        <property name="exceptionMappings">  
            <props>  
                <!-- 遇到MaxUploadSizeExceededException异常时,自动跳转到/view配置根目录/error_fileupload.jsp页面 -->  
                <prop key="org.springframework.web.multipart.MaxUploadSizeExceededException">error_fileupload</prop>  
            </props>  
        </property>  
    </bean>

三、 使用ajax方式上传文件
上面介绍的是通过正常提交表单的方式进行文件的上传,有时需要通过ajax的方式进行文件的上传。本文介绍的是基于jquery的jquery.form.js这个插件来实现的ajax上传文件

1.前台页面

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>  
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
<html>  
<head>  
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
    <title>Hello World</title>  
    <script type="text/javascript" src="<c:url value='/resources/3rdparty/jquery/jquery-2.1.1.min.js'/>"></script>
    <script type="text/javascript" src="<c:url value='/resources/3rdparty/jquery/jquery.form.js'/>"></script>
</head>  
<body>  
    <div>
        <div><span>文件名:</span><span>${filename }</span></div>
        <div><span>文件大小:</span><span>${size }</span></div>
        <form enctype="multipart/form-data" method="post" action="uploadfile">
            <input type="file" name="file"/>
            <input type="submit" value="submit"/>
        </form>
    </div>
    <script type="text/javascript">
        $(document).ready(function(){
            $("form").submit(function(evt){
                evt.preventDefault();
                $("form").ajaxSubmit({
                    url:"uploadfile",
                    dataType:"json",
                    type:"POST",
                    success: function(data){
                        console.log("data",data);
                    },
                    error: function(error){
                        console.log("error",error);
                    }
                });
            });
        });
    </script>
</body>  
</html>

2.后台处理

@RequestMapping(value = "/uploadfile",method=RequestMethod.POST)
@ResponseBody
public Map<String,Object> uploadfileUpload(HttpServletRequest req,HttpServletResponse resp,MultipartFile file) throws Exception {

        Map<String,Object> map = new HashMap<String,Object>();
        map.put("filename", file.getOriginalFilename());
        map.put("size", file.getSize()/(1024.0*1024) + "M");

        return map;
    }

四、 获取文件上传进度
1.使用jquery.form.js插件获取上传进度

$("form").ajaxSubmit({
                    url:"uploadfile",
                    dataType:"json",
                    type:"POST",
                    uploadProgress: function(event,position,total,percentComplete){
                        console.log("event",event);
                        console.log("position",position);
                        console.log("total",total);
                        console.log("percentComplete",percentComplete);
                    },
                    success: function(data){
                        console.log("data",data);
                    },
                    error: function(error){
                        console.log("error",error);
                    }
                });

Form插件的ajaxSubmit中的配置项uploadProgress就是用来获取文件上传进度的回调函数。注意这个回调函数中获取的是上传文件的总进度,也就是说同时上传多个文件时,这个回调中的参数信息是所有文件上传的总进度。

2.通过实现org.apache.commons.fileupload.ProgressListener接口
这种方式的原理是通过实现org.apache.commons.fileupload.ProgressListener接口的方法,继承org.springframework.web.multipart.commons.CommonsMultipartResolver重新实现相应的方法,将进度监听器设置到文件上传类中。进度监听器则将文件上传的进度信息保存在session中,这样前台请求进度信息时,后台就可以通过session获取。
1) 构造保存进度信息的实体类
可以根据自己的想要的信息自行设计

public class UploadFileProgressEntity {
    private long pBytesRead = 0L;//已读的byte总数
    private long pContentLength = 0L;//要读的文件总byte数,如果长度未知,值为-1
    private int pItems=0;//当前所读文件的索引(从1开始),单文件上传时始终为1,0表示没有文件在读

    public long getpBytesRead() {  
        return pBytesRead;  
    }  

    public void setpBytesRead(long pBytesRead) {  
        this.pBytesRead = pBytesRead;  
    }  

    public long getpContentLength() {  
        return pContentLength;  
    }  

    public void setpContentLength(long pContentLength) {  
        this.pContentLength = pContentLength;  
    } 

    public int getpItems() {  
        return pItems;  
    }  

    public void setpItems(int pItems) {  
        this.pItems = pItems;  
    }  
}

2) 实现org.apache.commons.fileupload.ProgressListener接口

public class UploadFileProgressListener implements ProgressListener {
    private HttpSession session;

    public UploadFileProgressListener(HttpSession session) {
        this.session = session;
        UploadFileProgressEntity ps = new UploadFileProgressEntity();  
        session.setAttribute("uploadFileProgressEntity", ps); 
    }
    @Override
    public void update(long pBytesRead, long pContentLength, int pItems) {
        UploadFileProgressEntity ps = (UploadFileProgressEntity)session.getAttribute("uploadFileProgressEntity");
        ps.setpBytesRead(pBytesRead);
        ps.setpContentLength(pContentLength);
        ps.setpItems(pItems);
        session.setAttribute("uploadFileProgressEntity", ps); 
    }

}

3) 重写类

org.springframework.web.multipart.commons.CommonsMultipartResolver 
public class MyCommonsMultipartResolver extends CommonsMultipartResolver {
    private HttpServletRequest request; 

    /**
     * 初始化org.apache.commons.fileupload.servlet.ServletFileUpload实例
     */
    protected FileUpload newFileUpload(FileItemFactory fileItemFactory) {  
        ServletFileUpload upload = new ServletFileUpload(fileItemFactory);  
        upload.setSizeMax(-1);  
        if (request != null) {  
            HttpSession session = request.getSession();  
            UploadFileProgressListener uploadProgressListener = new UploadFileProgressListener(session);  
            upload.setProgressListener(uploadProgressListener);  
        }  
        return upload;  
    }  

    /**
     * 将HttpServletRequest包装为MultipartHttpServletRequest,重载该方法获取HttpServletRequest,从而取得session
     */
    public MultipartHttpServletRequest resolveMultipart(  
            HttpServletRequest request) throws MultipartException {  
        this.request = request;// 获取到request,要用到session  
        return super.resolveMultipart(request);  
    }  

    @SuppressWarnings("unchecked")  
    @Override  
    public MultipartParsingResult parseRequest(HttpServletRequest request) throws MultipartException {  

        HttpSession session = request.getSession();  

        String encoding = "utf-8";  
        FileUpload fileUpload = prepareFileUpload(encoding);//这个函数内调用  newFileUpload()

        UploadFileProgressListener uploadProgressListener = new UploadFileProgressListener(session);  
        fileUpload.setProgressListener(uploadProgressListener);  
        try {  
            List<FileItem> fileItems = ((ServletFileUpload) fileUpload).parseRequest(request);  
            return parseFileItems(fileItems, encoding);  
        } catch (FileUploadBase.SizeLimitExceededException ex) {  
            throw new MaxUploadSizeExceededException(fileUpload.getSizeMax(), ex);  
        }  catch (FileUploadException ex) {  
            throw new MultipartException("Could not parse multipart servlet request", ex);  
        }  
    }  
}

4) 后台获取进度信息

@RequestMapping(value = "/uploadfile/progess",method=RequestMethod.GET)
@ResponseBody
public Map<String,Object> uploadfileUploadProgress(HttpServletRequest req,HttpServletResponse resp) throws Exception {
        HttpSession session = req.getSession();
        UploadFileProgressEntity ps = (UploadFileProgressEntity)session.getAttribute("uploadFileProgressEntity");

        Map<String,Object> map = new HashMap<String,Object>();
        if (null == ps) {
            map.put("progress", "");
        } else {
            map.put("progress", ps);
        }

        return map;
    }

5) 前台获取进度信息

$(document).ready(function(){
            window.getProgess = function(){
                $.ajax({
                       type: "GET",
                       url: "uploadfile/progess",
                       success: function(data){
                         console.log("progess",data);
                       }
                    }); 
            };
            window.getProgressTimer = null;

            $("form").submit(function(evt){
                evt.preventDefault();
                $("form").ajaxSubmit({
                    url:"uploadfile",
                    dataType:"json",
                    type:"POST",
                    beforeSubmit: function(){
                        window.getProgressTimer = setInterval("window.getProgess()",1000);
                    },
                    /*uploadProgress: function(event,position,total,percentComplete){
                        console.log("event",event);
                        console.log("position",position);
                        console.log("total",total);
                        console.log("percentComplete",percentComplete);
                    },*/
                    success: function(data){
                        console.log("data",data);
                        clearInterval(window.getProgressTimer);
                    },
                    error: function(error){
                        console.log("error",error);
                        clearInterval(window.getProgressTimer);
                    }
                });
            });
        });

6) 修改Spring配置文件
在上面说到了Spring上传文件要增加org.springframework.web.multipart.commons.CommonsMultipartResolver类的bean的配置,这里重写了这个类,所以要将这个bean配置为重写的类:

<bean id="multipartResolver" class="cn.com.helloword.util.uploadfile.MyCommonsMultipartResolver">  
        <property name="defaultEncoding" value="UTF-8"/>  
        <!-- 指定所上传文件的总大小,单位字节。注意maxUploadSize属性的限制不是针对单个文件,而是所有文件的容量之和 -->  
        <property name="maxUploadSize" value="1073741824"/>  
</bean>  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值