• 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 })
    View Code

    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被删除.

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

  • 相关阅读:
    SQL Server索引进阶:第九级,读懂执行计划
    SQL Server索引进阶:第八级,唯一索引
    SQL Server索引进阶:第七级,过滤的索引
    SQL Server索引进阶:第六级,标签
    SQL Server索引进阶:第五级,包含列
    SQL Server索引进阶:第四级,页和区
    SQL Server索引进阶:第三级,聚集索引
    SQL Server索引进阶:第二级,深入非聚集索引
    SQL Server索引进阶:第一级,索引简介
    2018 – 2019 年前端 JavaScript 面试题
  • 原文地址:https://www.cnblogs.com/guoyansi19900907/p/4757046.html
Copyright © 2020-2023  润新知