spring mvc分别用表单和ajax实现文件上传

1.需要提前准备好的配置文件

1>配置文件web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    version="2.5">
    <display-name>testmavenspringmvc</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>
    <!-- 全局初始化数据,spring的监听器读取此配置文件
    多个配置文件用分号分隔 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:conf/spring.xml</param-value>
    </context-param>
    <!-- spring容器初始化的监听器,会读取全局初始化的数据(xml文件) -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!-- spring处理中文乱码问题 -->
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!-- restful和非restful虽然能并存,但实际开发中,二者选其一 -->
    <!-- spring mvc的入口 加载spring mvc 前端控制器  非restful-->
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:conf/spring_mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
    <!-- spring mvc的入口 加载spring mvc 前端控制器 restful -->
    <!-- restful模式,必须注意在spring-mvc.xml中配置,刨除静态资源 -->
    <servlet>
        <servlet-name>dispatcher_restful</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:conf/spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher_restful</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    

</web-app>

2>spring-mvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:util="http://www.springframework.org/schema/util" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/util
        http://www.springframework.org/schema/util/spring-util.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 在restful模式下,添加静态资源 -->
    <mvc:resources location="/js/" mapping="/js/**"></mvc:resources>
    <mvc:resources location="/" mapping="/**"></mvc:resources>

    <!-- 扫描spring的组件 -->
    <context:component-scan base-package="com.tarena.controller"></context:component-scan>


    <!-- 扫描 spring mvc的注解 @RequestMapping @ResponseBody -->
    <mvc:annotation-driven></mvc:annotation-driven>
    
    <!--拦截器的配置部分-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--需要拦截的地址-->
            <mvc:mapping path="/**" />
            <!--不需要拦截的地址-->
            <mvc:exclude-mapping path="/login_restful.html" />
            <mvc:exclude-mapping path="/js/**" />
            <mvc:exclude-mapping path="/user_restful/**" />
            <!--定义拦截器类-->
            <bean class="com.tarena.interceptor.SecurityInterceptor"></bean>
        </mvc:interceptor>
     </mvc:interceptors>
    
    
    <!-- spring mvc处理响应的jsp -->
    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

    <bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--能配置多少个property,可以查文档和查询源代码 -->
        <!--最大上传文件的大小 -->
        <property name="maxUploadSize" value="8388608"></property>
        <property name="resolveLazily" value="true"></property>
    </bean>

</beans>


2.表单提交

1>html文件

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <div style="text-align:center;">
        <form action="fileupload/upload.do" method="post" enctype="multipart/form-data">
            <input type="text" name="fileDesc" /><br />
            <input type="file" name="fileName" /><br />
            <input type="submit" value="上传" />
        </form>
    
    </div>

</body>
</html>

2>controller中的代码

@Controller
@RequestMapping("/fileupload")
public class UploadController {
    @RequestMapping(value = "/upload.do", method = RequestMethod.POST)
    public String upload(@RequestParam(value = "fileName", required = false) MultipartFile file,
            @RequestParam(value = "fileDesc") String desc, HttpServletRequest request, ModelMap model) {
        String result = "error";
        System.out.println("fileDesc=" + desc);
        // 准备出文件上传到服务器中的哪个目录中
        String realPath = request.getServletContext().getRealPath("/upload");
        File realPathFile = new File(realPath);
        if (!realPathFile.exists())
            realPathFile.mkdir();

        // 判断文件是否为空
        if (!file.isEmpty()) {
            // 获取上传文件的信息
            String orifileName = file.getOriginalFilename();
            System.out.println("原始文件名=" + orifileName);
            String contentType = file.getContentType();
            System.out.println("原始文件类型=" + contentType);
            String name = file.getName();
            System.out.println("表单元素的名字=" + name);
            long size = file.getSize();
            System.out.println("文件的容量=" + size);
            try {
                if (!"image/png".equals(contentType)) {
                    // 保存文件
                    file.transferTo(new File(realPath, orifileName));

                    // 构建页面提示信息
                    String message = "文件上传成功,文件的位置" + request.getContextPath() + "/upload/" + orifileName;
                    model.addAttribute("message", message);
                    result = "success";
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                model.addAttribute("message", "文件上传失败");
            }

        }
        return result;
    }

}

3.ajax实现文件上传

1>js文件

jQuery.extend({
    createUploadIframe: function (id, uri) {//id为当前系统时间字符串,uri是外部传入的json对象的一个参数
        //create frame
        var frameId = 'jUploadFrame' + id; //给iframe添加一个独一无二的id
        var iframeHtml = '<iframe id="' + frameId + '" name="' + frameId + '" style="position:absolute; top:-9999px; left:-9999px"'; //创建iframe元素
        if (window.ActiveXObject) {//判断浏览器是否支持ActiveX控件
            if (typeof uri == 'boolean') {
                iframeHtml += ' src="' + 'javascript:false' + '"';
            }            else if (typeof uri == 'string') {
                iframeHtml += ' src="' + uri + '"';
            }
        }
        iframeHtml += ' />';
        jQuery(iframeHtml).appendTo(document.body); //将动态iframe追加到body中
        return jQuery('#' + frameId).get(0); //返回iframe对象
    },
    createUploadForm: function (id, fileElementId, data) {//id为当前系统时间字符串,fileElementId为页面<input type='file' />的id,data的值需要根据传入json的键来决定
        //create form    
        var formId = 'jUploadForm' + id; //给form添加一个独一无二的id
        var fileId = 'jUploadFile' + id; //给<input type='file' />添加一个独一无二的id
        var form = jQuery('<form  action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data" ></form>'); //创建form元素
        if (data) {//通常为false
            for (var i in data) {
                jQuery('<input type="hidden" name="' + i + '" value="' + data[i] + '" />').appendTo(form); //根据data的内容,创建隐藏域,这部分我还不知道是什么时候用到。估计是传入json的时候,如果默认传一些参数的话要用到。
            }
        }        var oldElement = jQuery('#' + fileElementId); //得到页面中的<input type='file' />对象
        var newElement = jQuery(oldElement).clone(); //克隆页面中的<input type='file' />对象
        jQuery(oldElement).attr('id', fileId); //修改原对象的id
        jQuery(oldElement).before(newElement); //在原对象前插入克隆对象
        jQuery(oldElement).appendTo(form); //把原对象插入到动态form的结尾处
        //set attributes
        jQuery(form).css('position', 'absolute'); //给动态form添加样式,使其浮动起来,
        jQuery(form).css('top', '-1200px');
        jQuery(form).css('left', '-1200px');
        jQuery(form).appendTo('body'); //把动态form插入到body中
        return form;
    },
    ajaxFileUpload: function (s) {//这里s是个json对象,传入一些ajax的参数
        // TODO introduce global settings, allowing the client to modify them for all requests, not only timeout        
        s = jQuery.extend({}, jQuery.ajaxSettings, s); //此时的s对象是由jQuery.ajaxSettings和原s对象扩展后的对象
        var id = new Date().getTime(); //取当前系统时间,目的是得到一个独一无二的数字
        var form = jQuery.createUploadForm(id, s.fileElementId, (typeof (s.data) == 'undefined' ? false : s.data)); //创建动态form
        var io = jQuery.createUploadIframe(id, s.secureuri); //创建动态iframe
        var frameId = 'jUploadFrame' + id; //动态iframe的id
        var formId = 'jUploadForm' + id; //动态form的id
        // Watch for a new set of requests
        if (s.global && !jQuery.active++) {//当jQuery开始一个ajax请求时发生
            jQuery.event.trigger("ajaxStart"); //触发ajaxStart方法
        }        var requestDone = false; //请求完成标志
        // Create the request object
        var xml = {};        if (s.global)
            jQuery.event.trigger("ajaxSend", [xml, s]); //触发ajaxSend方法
        // Wait for a response to come back
        var uploadCallback = function (isTimeout) {//回调函数
            var io = document.getElementById(frameId); //得到iframe对象
            try {                if (io.contentWindow) {//动态iframe所在窗口对象是否存在
                    xml.responseText = io.contentWindow.document.body ? io.contentWindow.document.body.innerHTML : null;
                    xml.responseXML = io.contentWindow.document.XMLDocument ? io.contentWindow.document.XMLDocument : io.contentWindow.document;
                } else if (io.contentDocument) {//动态iframe的文档对象是否存在
                    xml.responseText = io.contentDocument.document.body ? io.contentDocument.document.body.innerHTML : null;
                    xml.responseXML = io.contentDocument.document.XMLDocument ? io.contentDocument.document.XMLDocument : io.contentDocument.document;
                }
            } catch (e) {
                jQuery.handleError(s, xml, null, e);
            }            if (xml || isTimeout == "timeout") {//xml变量被赋值或者isTimeout == "timeout"都表示请求发出,并且有响应
                requestDone = true; //请求完成
                var status;                try {
                    status = isTimeout != "timeout" ? "success" : "error"; //如果不是“超时”,表示请求成功
                    // Make sure that the request was successful or notmodified
                    if (status != "error") {                        // process the data (runs the xml through httpData regardless of callback)
                        var data = jQuery.uploadHttpData(xml, s.dataType); //根据传送的type类型,返回json对象,此时返回的data就是后台操作后的返回结果
                        // If a local callback was specified, fire it and pass it the data
                        if (s.success)
                            s.success(data, status); //执行上传成功的操作
                        // Fire the global callback
                        if (s.global)
                            jQuery.event.trigger("ajaxSuccess", [xml, s]);
                    } else
                        jQuery.handleError(s, xml, status);
                } catch (e) {
                    status = "error";
                    jQuery.handleError(s, xml, status, e);
                }                // The request was completed
                if (s.global)
                    jQuery.event.trigger("ajaxComplete", [xml, s]);                // Handle the global AJAX counter
                if (s.global && ! --jQuery.active)
                    jQuery.event.trigger("ajaxStop");                // Process result
                if (s.complete)
                    s.complete(xml, status);
                jQuery(io).unbind();//移除iframe的事件处理程序
                setTimeout(function () {//设置超时时间
                    try {
                        jQuery(io).remove();//移除动态iframe
                        jQuery(form).remove();//移除动态form
                    } catch (e) {
                        jQuery.handleError(s, xml, null, e);
                    }
                }, 100)
                xml = null
            }
        }        // Timeout checker
        if (s.timeout > 0) {//超时检测
            setTimeout(function () {                // Check to see if the request is still happening
                if (!requestDone) uploadCallback("timeout");//如果请求仍未完成,就发送超时信号
            }, s.timeout);
        }        try {            var form = jQuery('#' + formId);
            jQuery(form).attr('action', s.url);//传入的ajax页面导向url
            jQuery(form).attr('method', 'POST');//设置提交表单方式
            jQuery(form).attr('target', frameId);//返回的目标iframe,就是创建的动态iframe
            if (form.encoding) {//选择编码方式
                jQuery(form).attr('encoding', 'multipart/form-data');
            }            else {
                jQuery(form).attr('enctype', 'multipart/form-data');
            }
            jQuery(form).submit();//提交form表单
        } catch (e) {
            jQuery.handleError(s, xml, null, e);
        }
        jQuery('#' + frameId).load(uploadCallback); //ajax 请求从服务器加载数据,同时传入回调函数
        return { abort: function () { } };
    },
    uploadHttpData: function (r, type) {        var data = !type;
        data = type == "xml" || data ? r.responseXML : r.responseText;        // If the type is "script", eval it in global context
        if (type == "script")
            jQuery.globalEval(data);        // Get the JavaScript object, if JSON is used.
        if (type == "json")
            eval("data = " + data);        // evaluate scripts within html
        if (type == "html")
            jQuery("<div>").html(data).evalScripts();        return data;
    }
})

2>ajax.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="js/common/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="js/ajaxfileupload.js"></script>
<script type="text/javascript" src="js/upload.js"></script>
</head>
<body>
    <div style="text-align:center;">
        <form id="upload_formid">
            <input type="text" name="fileDesc" /><br />
            <input id="fileid" type="file" name="fileName" /><br />
            <input type="button" value="上传" /><br />
        </form>
    </div>
</body>

</html>

3>controller中

@RequestMapping(value = "/uploadajax/desc/{desc}", method = RequestMethod.POST)
    @ResponseBody
    public Result uploadAjax(
            @RequestParam(value = "fileName", required = true) MultipartFile file,
            @PathVariable(value = "desc") String desc,
            HttpServletRequest request,
            HttpServletResponse response) {
        Result result=null;
        PrintWriter out=null;
        System.out.println("desc="+desc);
        
        try {
            out=response.getWriter();
            //指定上传的文件放在哪个目录中
            String realPath=request.getServletContext().getRealPath("/upload");
            File realPathFile=new File(realPath);
            if(!realPathFile.exists()) realPathFile.mkdir();
            
            if(!file.isEmpty()){
                String orifileName=file.getOriginalFilename();
                file.transferTo(new File(realPath,orifileName));
                out.print("上传成功");
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            out.print("上传失败");
        }
        out.close();
        return result;
    }

}

4表单批量上传

1>upload_batch.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="js/upload.js"></script>
</head>
<body>
    <div style="text-align:center;">
        <form method="post"
              action="fileupload/uploads.do"
              enctype="multipart/form-data">
          <table border="1" align="center">
              <tr>
                  <td>上传文件说明</td>
                  <td><input type="text" name="fileDesc" /></td>
              </tr>
              <tr>
                  <td>文件</td>
                  <td id="more">
                     <input type="file" name="fileName" />
                     <input type="button" value="添加..."
                            οnclick="addMore();"/>
                  </td>
              </tr>
              <tr>
                  <td colspan="2">
                      <input type="submit" value="上传" />
                  </td>
              </tr>
          </table>
        
        </form>
    </div>
</body>

</html>

2>upload.js

$(function(){
    $("#upload_formid input[type=button]").click(function(){
        upload_file();
    });
});
function upload_file(){
    //取出非文件域的内容
    var desc=$("#upload_formid input[type=text]").val();
    //文件上传
    $.ajaxFileUpload({
        url:"/testmavenspringmvc/fileupload/uploadajax/desc/"+desc,
        secureuri:false,
        fileElementId:"fileid",
        type:"post",
        dataType:"text",
        success:function(data,status){
            alert(data);
            data=data.replace(/<PRE.*?>/g,'');
            data=data.replace("<PRE>",'');
            data=data.replace("</PRE>",'');
            data=data.replace(/<pre.*?>/g,'');
            data=data.replace("<pre>",'');
            data=data.replace("</pre>",'');
            alert(data);
        },
        error:function(){
            alert("请求失败!");
        }
    });
}

function addMore(){
    var td_ele=document.getElementById("more");
    
    var br_ele=document.createElement("br");
    
    var input_file=document.createElement("input");
    input_file.type="file";
    input_file.name="fileName";
    
    var input_button=document.createElement("input");
    input_button.type="button";
    input_button.value="删除";
    input_button.οnclick=function(){
        td_ele.removeChild(input_file);
        td_ele.removeChild(input_button);
        td_ele.removeChild(br_ele);
        
    };
    td_ele.appendChild(br_ele);
    td_ele.appendChild(input_file);
    td_ele.appendChild(input_button);

}

3>controller

@RequestMapping(value = "/uploads.do", method = RequestMethod.POST)
    public String uploads(@RequestParam(value = "fileName", required = false) MultipartFile[] files,
            @RequestParam(value = "fileDesc") String desc, HttpServletRequest request, ModelMap model) {
        String result = "error";
        System.out.println("fileDesc=" + desc);
        // 准备出文件上传到服务器中的哪个目录中
        String realPath = request.getServletContext().getRealPath("/upload");
        File realPathFile = new File(realPath);
        if (!realPathFile.exists())
            realPathFile.mkdir();
        String message="";
        // 判断文件是否为空
        if (files != null && files.length > 0) {
            for (MultipartFile file : files) {
                // 获取上传文件的信息
                String orifileName = file.getOriginalFilename();
                System.out.println("原始文件名=" + orifileName);
                String contentType = file.getContentType();
                System.out.println("原始文件类型=" + contentType);
                String name = file.getName();
                System.out.println("表单元素的名字=" + name);
                long size = file.getSize();
                System.out.println("文件的容量=" + size);
                try {
                    if (!"image/png".equals(contentType)) {
                        // 保存文件
                        file.transferTo(new File(realPath, orifileName));

                        // 构建页面提示信息
                        message += "文件上传成功,文件的位置"
                             + request.getContextPath()
                             + "/upload/"
                             + orifileName
                             +"<br />";
                        
                    }
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    model.addAttribute("message", "文件上传失败");
                }
            }
            model.addAttribute("message", message);
        }
        result="success";
        return result;
    }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值