springmvc+ajaxFileUpload上传文件(前后台彻底分离的情况下)

首先是导入jar包:

web.xml:

 1 <servlet>
 2       <servlet-name>mvc-dispatcher</servlet-name>
 3       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
 4           <init-param>
 5            <param-name>contextConfigLocation</param-name>
 6            <param-value>/WEB-INF/configs/mvc-dispatcher-servlet.xml</param-value>
 7        </init-param>
 8       <load-on-startup>1</load-on-startup>
 9   </servlet>
10   <servlet-mapping>
11       <servlet-name>mvc-dispatcher</servlet-name>
12       <!-- mvc-dispatcher 拦截所有的请求 -->
13       <url-pattern>*.g</url-pattern>
14   </servlet-mapping>

mvc-dispatcher-servlet.xml

  1 <?xml version="1.0" encoding="UTF-8"?>
  2 <beans xmlns="http://www.springframework.org/schema/beans"
  3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4     xmlns:p="http://www.springframework.org/schema/p"
  5     xmlns:context="http://www.springframework.org/schema/context"
  6     xmlns:mvc="http://www.springframework.org/schema/mvc"
  7     xmlns:tx="http://www.springframework.org/schema/tx"
  8     xmlns:aop="http://www.springframework.org/schema/aop"
  9     xsi:schemaLocation="
 10         http://www.springframework.org/schema/beans
 11         http://www.springframework.org/schema/beans/spring-beans.xsd
 12         http://www.springframework.org/schema/context
 13         http://www.springframework.org/schema/context/spring-context.xsd
 14         http://www.springframework.org/schema/mvc
 15         http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
 16         http://www.springframework.org/schema/tx
 17         http://www.springframework.org/schema/tx/spring-tx.xsd
 18         http://www.springframework.org/schema/aop
 19         http://www.springframework.org/schema/aop/spring-aop.xsd">
 20
 21 <!-- 激活
 22      @Required
 23      @Autowired,jsr250‘s
 24      @PostConstruct,
 25      @PreDestroy and @ Resource等标注
 26  -->
 27 <context:annotation-config />
 28 <!--
 29     DispatcherServlet上下文,只搜索@Controller标注的类,不搜索其他标注的类
 30  -->
 31 <context:component-scan base-package="com.test">
 32     <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
 33 </context:component-scan>
 34
 35 <!--
 36
 37     HandlerMapping无需配置,Spring MVC可以默认启动
 38  -->
 39  <!--
 40      扩充了注解驱动,可以将请求参数绑定到控制器参数
 41     启用基于annotation的handlerMapping.
 42   -->
 43 <!-- <mvc:annotation-driven /> -->
 44 <mvc:annotation-driven>
 45         <mvc:message-converters register-defaults="true">
 46             <bean class="org.springframework.http.converter.StringHttpMessageConverter">
 47                 <constructor-arg>
 48                     <bean class="java.nio.charset.Charset" factory-method="forName">
 49                         <constructor-arg value="UTF-8" />
 50                     </bean>
 51                 </constructor-arg>
 52             </bean>
 53
 54             <bean class="org.springframework.http.converter.StringHttpMessageConverter">
 55             <!-- 控制RequestBody返回值乱码 -->
 56               <property name="supportedMediaTypes" value = "text/plain;charset=UTF-8" />
 57             </bean>
 58
 59            </mvc:message-converters>
 60     </mvc:annotation-driven>
 61 <!--
 62     静态资源处理,css,js,imgs
 63  -->
 64 <mvc:resources location="/resources/" mapping="/resources/**"/>
 65
 66
 67 <!-- 视图解析器 -->
 68 <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
 69     <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
 70     <property name="prefix" value="/WEB-INF/jsps/" />
 71     <property name="suffix" value=".jsp" />
 72 </bean>
 73
 74 <!-- 配置上传文件代码,导入commons-fileupload-1.2.2.jar,commons-io-2.4.jar
 75     200*1024*1024即200M resolveLazily属性启用是为了推迟文件解析,以便捕获文件大小异常
 76  -->
 77 <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
 78     <!-- 上传的最大限制 -->
 79     <property name="maxUploadSize" value="209715200" />
 80     <!-- 默认编码 -->
 81     <property name="defaultEncoding" value="UTF-8" />
 82     <!-- 上传文件的解析 -->
 83     <property name="resolveLazily" value="true" />
 84 </bean>
 85
 86 <!-- 整合json,导入jackson-core-asl-1.1.2.jar,jackson-mapper-asl-1.1.2.jar
 87     配置ViewResolver.
 88     可以用多个ViewResolver.使用order属性排序.InternalResourceViewResolver放在最后
 89  -->
 90 <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
 91     <property name="order" value="1" />
 92     <property name="mediaTypes">
 93         <map>
 94             <entry key="json" value="application/json" />
 95             <entry key="xml" value="application/xml" />
 96             <entry key="htm" value="text/html" />
 97         </map>
 98     </property>
 99     <property name="defaultViews">
100         <list>
101         <!-- JSON View -->
102             <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"></bean>
103         </list>
104     </property>
105     <property name="ignoreAcceptHeader" value="true" />
106 </bean>
107 </beans>

UploadController.java

 1 @Controller
 2 @RequestMapping(value = "/mvc")
 3 public class UploadController {    /** 上传目录名*/      private static String uploadFolderName = "uploadFiles";        /** 允许上传的扩展名*/      private static String [] extensionPermit = {"txt","jpg","xls","zip"};
 4       /**
 5      * 上传文件
 6      * @param file
 7      * @return
 8      * @throws IOException
 9      */
10     @RequestMapping(value="/upload",method=RequestMethod.POST)
11     public String doUploadFile(@RequestParam("file") MultipartFile file) throws IOException{
12         if(!file.isEmpty()){
13             System.out.println("提示:"+file.getOriginalFilename());
14             FileUtils.copyInputStreamToFile(file.getInputStream(), new File("d:\\upload\\",System.currentTimeMillis()+file.getOriginalFilename()));
15         }
16         return "success";
17     }
18 }

最终这个文件会被上传到d:upload里面,可是我们想把代码上传到项目文件夹里面,做一些修改.

@Controller
@RequestMapping(value = "/mvc")
public class UploadController {    /** 上传目录名*/      private static final String uploadFolderName = "uploadFiles";        /** 允许上传的扩展名*/    private static String [] extensionPermit = {"txt","jpg","xls","zip"};
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public @ResponseBody String fileUpload(@RequestParam("file") CommonsMultipartFile file,
            HttpSession session, HttpServletRequest request, HttpServletResponse response) throws Exception{
        String curProjectPath = session.getServletContext().getRealPath("/");
        String saveDirectoryPath = curProjectPath + "/" + uploadFolderName;
        File saveDirectory = new File(saveDirectoryPath);
        logger.debug("Project real path [" + saveDirectory.getAbsolutePath() + "]");  

        // 判断文件是否存在
        if (!file.isEmpty()) {
            String fileName = file.getOriginalFilename();
            String fileExtension = FilenameUtils.getExtension(fileName);
            if(!Arrays.asList(extensionPermit).contains(fileExtension)){
                throw new Exception("No Support extension.");
            }
            FileUtils.copyInputStreamToFile(file.getInputStream(), new File(saveDirectoryPath,System.currentTimeMillis()+file.getOriginalFilename()));
        }
        logger.info("UploadController#fileUpload() end");
       return "{‘status‘:200,‘msg‘:‘上传成功‘}";

    }
}

运行后,在tomcat的项目目录里就可以找到新建的文件了.

后台代码编写完毕了,现在编写前台.

首先准备jquery,和ajaxfileupload.js

下载下来的ajaxfileupload.js需要做相应的修改,才能接收上传成功后从服务器返回的数据,

修改后才能和现在高版本的jquery相兼容.

具体改了哪些地方就不啰嗦了.我把改过的最终代码全部贴上来.

ajaxfileupload.js

  1 jQuery.extend({
  2
  3
  4     createUploadIframe: function (id, uri) {
  5         //create frame
  6         var frameId = ‘jUploadFrame‘ + id;
  7         var iframeHtml = ‘<iframe id="‘ + frameId + ‘" name="‘ + frameId + ‘" style="position:absolute; top:-9999px; left:-9999px"‘;
  8         if (window.ActiveXObject) {
  9             if (typeof uri == ‘boolean‘) {
 10                 iframeHtml += ‘ src="‘ + ‘javascript:false‘ + ‘"‘;
 11
 12             }
 13             else if (typeof uri == ‘string‘) {
 14                 iframeHtml += ‘ src="‘ + uri + ‘"‘;
 15
 16             }
 17         }
 18         iframeHtml += ‘ />‘;
 19         jQuery(iframeHtml).appendTo(document.body);
 20
 21         return jQuery(‘#‘ + frameId).get(0);
 22     },
 23     createUploadForm: function (id, fileElementId, data) {
 24         //create form
 25         var formId = ‘jUploadForm‘ + id;
 26         var fileId = ‘jUploadFile‘ + id;
 27         var form = jQuery(‘<form  action="" method="POST" name="‘ + formId + ‘" id="‘ + formId + ‘" enctype="multipart/form-data"></form>‘);
 28         if (data) {
 29             for (var i in data) {
 30                 if (data[i].name != null && data[i].value != null) {
 31                     jQuery(‘<input type="hidden" name="‘ + data[i].name + ‘" value="‘ + data[i].value + ‘" />‘).appendTo(form);
 32                 } else {
 33                     jQuery(‘<input type="hidden" name="‘ + i + ‘" value="‘ + data[i] + ‘" />‘).appendTo(form);
 34                 }
 35             }
 36         }
 37         var oldElement = jQuery(‘#‘ + fileElementId);
 38         var newElement = jQuery(oldElement).clone();
 39         jQuery(oldElement).attr(‘id‘, fileId);
 40         jQuery(oldElement).before(newElement);
 41         jQuery(oldElement).appendTo(form);
 42
 43
 44
 45         //set attributes
 46         jQuery(form).css(‘position‘, ‘absolute‘);
 47         jQuery(form).css(‘top‘, ‘-1200px‘);
 48         jQuery(form).css(‘left‘, ‘-1200px‘);
 49         jQuery(form).appendTo(‘body‘);
 50         return form;
 51     },
 52
 53     ajaxFileUpload: function (s) {
 54         // TODO introduce global settings, allowing the client to modify them for all requests, not only timeout
 55         s = jQuery.extend({}, jQuery.ajaxSettings, s);
 56         var id = new Date().getTime()
 57         var form = jQuery.createUploadForm(id, s.fileElementId, (typeof (s.data) == ‘undefined‘ ? false : s.data));
 58         var io = jQuery.createUploadIframe(id, s.secureuri);
 59         var frameId = ‘jUploadFrame‘ + id;
 60         var formId = ‘jUploadForm‘ + id;
 61         // Watch for a new set of requests
 62         if (s.global && !jQuery.active++) {
 63             jQuery.event.trigger("ajaxStart");
 64         }
 65         var requestDone = false;
 66         // Create the request object
 67         var xml = {}
 68         if (s.global)
 69             jQuery.event.trigger("ajaxSend", [xml, s]);
 70         // Wait for a response to come back
 71         var uploadCallback = function (isTimeout) {
 72             var io = document.getElementById(frameId);
 73             try {
 74                 if (io.contentWindow) {
 75                     xml.responseText = io.contentWindow.document.body ? io.contentWindow.document.body.innerHTML : null;
 76                     xml.responseXML = io.contentWindow.document.XMLDocument ? io.contentWindow.document.XMLDocument : io.contentWindow.document;
 77
 78                 } else if (io.contentDocument) {
 79                     xml.responseText = io.contentDocument.document.body ? io.contentDocument.document.body.innerHTML : null;
 80                     xml.responseXML = io.contentDocument.document.XMLDocument ? io.contentDocument.document.XMLDocument : io.contentDocument.document;
 81                 }
 82             } catch (e) {
 83                 jQuery.handleError(s, xml, null, e);
 84             }
 85             if (xml || isTimeout == "timeout") {
 86                 requestDone = true;
 87                 var status;
 88                 try {
 89                     status = isTimeout != "timeout" ? "success" : "error";
 90                     // Make sure that the request was successful or notmodified
 91                     if (status != "error") {
 92                         // process the data (runs the xml through httpData regardless of callback)
 93                         var data = jQuery.uploadHttpData(xml, s.dataType);
 94                         // If a local callback was specified, fire it and pass it the data
 95                         if (s.success)
 96                             s.success(data, status);
 97
 98                         // Fire the global callback
 99                         if (s.global)
100                             jQuery.event.trigger("ajaxSuccess", [xml, s]);
101                     } else
102                         jQuery.handleError(s, xml, status);
103                 } catch (e) {
104                     status = "error";
105                     jQuery.handleError(s, xml, status, e);
106                 }
107
108                 // The request was completed
109                 if (s.global)
110                     jQuery.event.trigger("ajaxComplete", [xml, s]);
111
112                 // Handle the global AJAX counter
113                 if (s.global && ! --jQuery.active)
114                     jQuery.event.trigger("ajaxStop");
115
116                 // Process result
117                 if (s.complete)
118                     s.complete(xml, status);
119
120                 jQuery(io).unbind()
121
122                 setTimeout(function () {
123                     try {
124                         jQuery(io).remove();
125                         jQuery(form).remove();
126
127                     } catch (e) {
128                         jQuery.handleError(s, xml, null, e);
129                     }
130
131                 }, 100)
132
133                 xml = null
134
135             }
136         }
137         // Timeout checker
138         if (s.timeout > 0) {
139             setTimeout(function () {
140                 // Check to see if the request is still happening
141                 if (!requestDone) uploadCallback("timeout");
142             }, s.timeout);
143         }
144         try {
145
146             var form = jQuery(‘#‘ + formId);
147             jQuery(form).attr(‘action‘, s.url);
148             jQuery(form).attr(‘method‘, ‘POST‘);
149             jQuery(form).attr(‘target‘, frameId);
150             if (form.encoding) {
151                 jQuery(form).attr(‘encoding‘, ‘multipart/form-data‘);
152             }
153             else {
154                 jQuery(form).attr(‘enctype‘, ‘multipart/form-data‘);
155             }
156             jQuery(form).submit();
157
158         } catch (e) {
159             jQuery.handleError(s, xml, null, e);
160         }
161
162         jQuery(‘#‘ + frameId).load(uploadCallback);
163         return { abort: function () { } };
164
165     },
166
167     uploadHttpData: function (r, type) {
168         var data = !type;
169         if (!type)
170             data = r.responseText;
171         if (type == "xml")
172             data = r.responseXML;
173         //data = type == "xml" || data ? r.responseXML : r.responseText;
174         // If the type is "script", eval it in global context
175         if (type == "script")
176             jQuery.globalEval(data);
177         // Get the JavaScript object, if JSON is used.
178         if (type == "json") {
179             ////////////Fix the issue that it always throws the error "unexpected token ‘<‘"///////////////
180             data = r.responseText;
181             var start = data.indexOf(">");
182             if (start != -1) {
183                 var end = data.indexOf("<", start + 1);
184                 if (end != -1) {
185                     data = data.substring(start + 1, end);
186                 }
187             }
188             ///////////////////////////////////////////////////////////////////////////////////////////////
189             eval("data = " + data);
190         }
191         // evaluate scripts within html
192         if (type == "html")
193             jQuery("<div>").html(data).evalScripts();
194
195         return data;
196     },
197
198     handleError: function (s, xhr, status, e) {
199         // If a local callback was specified, fire it
200         if (s.error) {
201             s.error.call(s.context || s, xhr, status, e);
202         }
203
204         // Fire the global callback
205         if (s.global) {
206             (s.context ? jQuery(s.context) : jQuery.event).trigger("ajaxError", [xhr, s, e]);
207         }
208     }
209 })

html代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>上传页面三</title>
<script type="text/javascript" src="static/js/jquery-1.7.2.js"></script>
<script type="text/javascript" src="static/js/ajaxfileupload.js"></script>
</head>

<body>
    <h2>JQuery ajaxfileupload文件上传</h2>
    <div id="loading" style="display: none;">正在上传.....</div>
    用户信息:
    <br /> 姓名:
    <input id="name" name="name" type="text">
    <br /> 附件:
    <input id="fileToUpload" name="file" type="file" class="input">
    <br />
    <input type="button" onclick="ajaxFileUpload()" value="上传">
    <br />

    <script type="text/javascript">
        function ajaxFileUpload() {
            $(‘#loading‘).show();
            $.ajaxFileUpload({
                url : ‘mvc/upload.g‘,
                secureuri : false,
                fileElementId : ‘fileToUpload‘,
                dataType : ‘json‘,//此时指定的是后台需要返回json字符串,前端自己解析,可以注释掉.后台直接返回map
                data : {
                    name : $(‘#name‘).val()
                },
                success : function(data, status) {
                    alert("success");
                    console.log(data);
                    $(‘#loading‘).hide();
                },
                error : function(data, status, e) {
                    $(‘#loading‘).hide();
                    //这里处理的是网络异常,返回参数解析异常,DOM操作异常
                    alert("上传发生异常");
                }
            })
        }
    </script>
</body>
</html>

好,结束.

当你程序跑起来的时候,打开控制台你是看不到ajax提交请求的.因为ajaxFileupload.js上传的 原理是:form表单+iframe提交的.

服务器端返回的数据最终会进入到iframe里面的.通过修改ajaxFileUpload.js把这个数据从ifram中解析出来.

这个过程可以在success里加个alert,阻止脚本执行,来观察到.当success执行完毕后,form和iframe被删除.

可以结合前面的上传博客来更好地理解这里.

时间: 2025-01-04 07:50:47

springmvc+ajaxFileUpload上传文件(前后台彻底分离的情况下)的相关文章

【SpringMVC】使用SpringMVC进行上传文件!

写在前面: 之前在上传文件的时候,使用的是commons-file-upload这个插件,非常方便,能控制每个文件的大小,总共大小,缓存,以及支持多个文件的同时上传,但是写一次上传文件的后台代码量太大了,如图 如果有多个地方都要上传文件,每一次都要复制,粘贴一遍又一遍,实在是太麻烦,后台想到能不能把相同的代码都封装到一个方法,然后需要使用的时候再稍微改一下就行了,在封装的过程中,发现原来SpringMVC有自带的上传文件组件,遂用了一下,感觉多然很方面! 下面详细的说一下使用步骤! 1,准备好相

ajaxFileUpload上传文件后提示下载的问题

在某些版本浏览器下ajaxFileUpload上传文件会提示下载, 1:为什么? 可以观察到,即便返回 JsonResult 在返回的头中也没有任何消息体,直接理解为文本了. 2:解决方案 前端: function uploadImg(fimgi) {    if ($("#fimg" + fimgi).val().length > 0) {        //alert($("#fimg" + fimgi).val().length); }    else

在使用 AjaxFileUpload 上传文件时,在项目发布到 iis 后,图片不能预览

在使用 AjaxFileUpload  上传文件时,图片已经上传成功了,在站点没有发布时,可以预览,可是在项目发布到 iis 后,图片就不能预览,在网上找了很多的方案也没解决,最后的解决方案如下: 1.开始运行 regedit 打开注册表,先备份注册表 2.找到 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HTTP\Parameters 3.在 编辑 菜单上指向 新建 ,然后单击 DWORD 值 . 4.键入 EnableAggres

用ajaxFileUpLoad上传文件不能正确取得返回值的问题

刚开始没有觉得ajax请求的dataType参数的重要性,用了ajaxFileUpLoad插件后,如果页面代码如下: fileElementId : ['imageToUpload'], url : 'url', dataType : 'json', 返回类型为json数据,那么后台处理上传后,必须将返回值封装成json格式的数据返回给前台页面. 后台封装如下: return "{\"result\":" + "\"OK\"}"

ajaxfileupload上传文件,返回json数据报错的问题。

在使用ajaxfileupload上传文件的时候,文件上传成功了,但是返回的json数据一直解析不了.一直提示:Resource interpreted as Document but transferred with MIME type application/json,从字面上理解返回的是文档不能转换为json.但是从服务器那边返回的response里data-type确实是applicaiton/json.困扰很久,查看ajaxfileupload源代码发现,其实ajaxfileuploa

SpringMVC+ajaxfileupload上传

看这篇的文章之前最好看一下上篇文章这样可以更好的理解! 整个项目的基本配置和上面差不多 不同的是在webRoot文件夹下的js中引入jQuery.js 和ajaxfileupload.js 如何没有这个两个js文件可以到各自的官网下载 现在说说其他的不同之处 DemoController.java   跳转到upload.jsp package com.iss.controller; import org.springframework.stereotype.Controller; import

SpringMVC 学习-上传文件分解器 CommonsMultipartResolver 类

Spring 组件 CommonsMultipartResolver 类的主要作用是配置文件上传的一些属性,也可以控制上传文件的大小. 在 springmvc-servlet.xml 配置文件中: <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="d

ajaxFileUpload上传文件成功后却无法解析服务器返回的json数据

ajaxFileUpload是一款很好用的文件上传插件,网上也有很多关于它的版本,但在上传文件成功后想返回json数据给前台时,却会出现无法解析json数据的情况. 仔细调试发现其实在向服务器提交数据后,是进入了success回调函数的,只是没有解析到json数据.那就说明服务器做出了响应的,进入了success方法的,唯一的问题就是前台接受的数据不是json格式的. 使用console.log输出data发现并不是纯粹的json数据,其中头部多了<pre style="word-wrap

SPRINGMVC模式上传文件

这里包括三个上传的方式都是项目当中用到过的,都是大同小异主要还是运用SPRINGMVC里面的 MultipartFile file package com.xiaoquan.approval.controller.admin; import java.io.File;import java.text.DateFormat;import java.text.SimpleDateFormat;import java.util.Arrays;import java.util.Date;import j