ajax 上次附件(一个或者多个)

标签: ajax | 发表时间:2014-06-16 19:39 | 作者:一米天空
出处:http://www.iteye.com

      最近自己的项目需要开发一个ajax上传和下载的功能集成在springmvc项目中,最近公司工作比较轻松,就研究了一下这个东西,希望对大家有所帮助。

  一。上传单个文件

       1.需要jar文件

        commons-io.jar

        commons-fileupload.jar

       2.配置applicationContext.xml配置

               
    <mvc:resources mapping="/upload/**" location="/upload/"/>
 
    <!-- SpringMVC上传文件时,需配置MultipartResolver处理器 -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 指定所上传文件的总大小不能超过800KB......注意maxUploadSize属性的限制不是针对单个文件,而是所有文件的容量之和 -->
  
    <!-- set the max upload size1MB   1048576     -->
        <property name="maxUploadSize">
            <value>82428800</value>
        </property>
        <property name="maxInMemorySize">
            <value>2048</value>
        </property>
   
    </bean>
 
    <!-- SpringMVC在超出上传文件限制时,会抛出org.springframework.web.multipart.MaxUploadSizeExceededException -->
    <!-- 该异常是SpringMVC在检查上传的文件信息时抛出来的,而且此时还没有进入到Controller方法中 -->
    <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="exceptionMappings">
        <props>
        <!-- 遇到MaxUploadSizeExceededException异常时,自动跳转到/WEB-INF/jsp/error_fileupload.jsp页面 -->
        <prop key="org.springframework.web.multipart.MaxUploadSizeExceededException">error_fileupload</prop>
        </props>
    </property>
    </bean>
 
 <!-- SpringMVC在超出上传文件限制时,会抛出org.springframework.web.multipart.MaxUploadSizeExceededException -->
 <!-- 该异常是SpringMVC在检查上传的文件信息时抛出来的,而且此时还没有进入到Controller方法中 -->
 <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
  <property name="exceptionMappings">
   <props>
    <!-- 遇到MaxUploadSizeExceededException异常时,自动跳转到/WEB-INF/error_fileupload.jsp页面 -->
    <prop key="org.springframework.web.multipart.MaxUploadSizeExceededException">WEB-INF/error_fileupload</prop>
    <!-- 处理其它异常(包括Controller抛出的) -->
    <prop key="java.lang.Throwable">WEB-INF/500</prop>
   </props>
  </property>
 </bean>

3.新增一个上传页面

    <%@ page language="java" pageEncoding="UTF-8"%>
<%@ include file="/common/taglibs.jsp"%>
<%@ include file="/common/headcj.jsp"%>
<html>
  <head>
    <!-- 执行上传文件操作的函数 -->
      <script type="text/javascript">
          function ajaxFileUpload(){
            $.ajaxFileUpload({
       //处理文件上传操作的服务器端地址(可以传参数,已亲测可用) 
       url:'${ctx}/file/imgupload',
       secureuri:false,                       //是否启用安全提交,默认为false
       fileElementId:'myBlogImage',           //文件选择框的id属性
       dataType:'text',                       //服务器返回的格式,可以是json或xml等
       success:function(data, status){        //服务器响应成功时的处理函数
           alert(data);
           data = data.replace("<PRE>", '');  //ajaxFileUpload会对服务器响应回来的text内容加上<pre>text</pre>前后缀
           data = data.replace("</PRE>", '');
           data = data.replace("<pre>", '');
           data = data.replace("</pre>", ''); //本例中设定上传文件完毕后,服务端会返回给前台[0`filepath]
           if(data.substring(0, 1) == 0){     //0表示上传成功(后跟上传后的文件路径),1表示失败(后跟失败描述)
            $("img[id='uploadImage']").attr("src", data.substring(2));
            $('#result').html("图片上传成功<br/>");
           }else{
            $('#result').html('图片上传失败,请重试!!');
           }
       },
       error:function(data, status, e){ //服务器响应失败时的处理函数
           $('#result').html('图片上传失败,请重试!!');
       }
       });
                          
          }
      </script>
  </head>
 
  <body>
      <div>
        <input type="file" id="myBlogImage" name="imgFile"/>
        <input type="button" value="提交" onclick="ajaxFileUpload()"/>
    </div>
    <div id="result"></div>
   
  </body>
</html>

4.新增java接收方法

     /**
     * 这里这里用的是MultipartFile[] myfiles参数,所以前台就要用<input type="file" name="myfiles"/>
     * 上传文件完毕后返回给前台[0`filepath],0表示上传成功(后跟上传后的文件路径),1表示失败(后跟失败描述)
  * @throws IOException   @RequestParam("uname") String uname,
     */
 @RequestMapping(value="/fileUpload",method=RequestMethod.POST)
 @ResponseBody
 public String SaveFile(@RequestParam("uname") String uname,@RequestParam MultipartFile[] myfiles, HttpServletRequest request, HttpServletResponse response) throws IOException{
  //可以在上传文件的同时接收其它参数
 // System.out.println("收到用户[" + uname + "]的文件上传请求");
  //如果用的是Tomcat服务器,则文件会上传到 \\%TOMCAT_HOME%\\webapps\\YourWebProject\\upload\\文件夹中
  //这里实现文件上传操作用的是commons.io.FileUtils类,它会自动判断/upload是否存在,不存在会自动创建
  String realPath = request.getSession().getServletContext().getRealPath("/upload");
  //设置响应给前台内容的数据格式
  response.setContentType("text/plain; charset=UTF-8");
  //设置响应给前台内容的PrintWriter对象
  PrintWriter out = response.getWriter();
  //上传文件的原名(即上传前的文件名字)
  String originalFilename = null;
  //如果只是上传一个文件,则只需要MultipartFile类型接收文件即可,而且无需显式指定@RequestParam注解
  //如果想上传多个文件,那么这里就要用MultipartFile[]类型来接收文件,并且要指定@RequestParam注解
  //上传多个文件时,前台表单中的所有<input type="file"/>的name都应该是myfiles,否则参数里的myfiles无法获取到所有上传的文件
  for(MultipartFile myfile : myfiles){
   if(myfile.isEmpty()){
    out.print("1`请选择文件后上传");
    out.flush();
    return null;
   }else{
    originalFilename = myfile.getOriginalFilename();
    System.out.println("文件原名: " + originalFilename);
    System.out.println("文件名称: " + myfile.getName());
    System.out.println("文件长度: " + myfile.getSize());
    System.out.println("文件类型: " + myfile.getContentType());
    System.out.println("========================================");
    try {
     //这里不必处理IO流关闭的问题,因为FileUtils.copyInputStreamToFile()方法内部会自动把用到的IO流关掉
     //此处也可以使用Spring提供的MultipartFile.transferTo(File dest)方法实现文件的上传
      FileUtils.copyInputStreamToFile(myfile.getInputStream(), new File(realPath, originalFilename));

    } catch (IOException e) {
     System.out.println("文件["+ originalFilename + "]上传失败,堆栈轨迹如下");
     e.printStackTrace();
     out.print("1`文件上传失败,请重试!!");
     out.flush();
     return null;
    }
   }
  }
  //此时在Windows下输出的是[D:\Develop\apache-tomcat-6.0.36\webapps\AjaxFileUpload\\upload\愤怒的小鸟.jpg]
  //System.out.println(realPath + "\\" + originalFilename);
  //此时在Windows下输出的是[/AjaxFileUpload/upload/愤怒的小鸟.jpg]
  //System.out.println(request.getContextPath() + "/upload/" + originalFilename);
  //不推荐返回[realPath + "\\" + originalFilename]的值
  //因为在Windows下<img src=" file:///D:/aa.jpg">能被firefox显示,而<img src="D:/aa.jpg">firefox是不认的
  out.print("0`" + request.getContextPath() + "/upload/" + originalFilename);
  out.flush();
  return null;
 }

二 。上传多个文件

   1.修改fileupload.js文件,将form拼接部分进行修改成   

createUploadForm: function(id, fileElementId, data)
{
 //create form
    var formId = 'jUploadForm' + id[0];
    var fileId = 'jUploadFile' + id;
    var form = jQuery('<form  action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');
    if (data) {
  for ( var i in data) {
   jQuery(
     '<input type="hidden" name="' + i + '" value="'
       + data[i] + '" />').appendTo(form);
  }
 }
    for (var i = 0; i < fileElementId.length; i++) {
  var oldElement = jQuery('#' + fileElementId[i]);
  var newElement = jQuery(oldElement).clone();
  jQuery(oldElement).attr('id', fileElementId[i]);
  jQuery(oldElement).attr('name', fileElementId[i]);
  jQuery(oldElement).before(newElement);
  jQuery(oldElement).appendTo(form);
 }
    //set attributes
    jQuery(form).css('position', 'absolute');
    jQuery(form).css('top', '-1200px');
    jQuery(form).css('left', '-1200px');
    jQuery(form).appendTo('body');
 return form;
   }

 2.html上传文件

<%@ page language="java" pageEncoding="UTF-8"%>
<%@ include file="/common/taglibs.jsp"%>
<%@ include file="/common/headcj.jsp"%>
<html>
  <head>
 <script type="text/javascript" src="${ctx }/js/common/dajaxfileupload.js"></script>
    <!-- 执行上传文件操作的函数 -->
      <script type="text/javascript">
       var count = 1;
  /**
  * 生成多附件上传框
  */
  function createInput(parentId){
      count++;
      var str = '<div name="div" ><font style="font-size:12px;">附件</font>'+
      '   '+ '<input type="file" contentEditable="false" id="uploads' + count + '' +
      '" name="uploads'+ count +'" value="" style="width: 220px"/><input type="button"  value="删除" onclick="removeInput(event)" />'+'</div>';
      document.getElementById(parentId).insertAdjacentHTML("beforeEnd",str);
  }
  /**
  * 删除多附件删除框
  */
  function removeInput(evt, parentId){
     var el = evt.target == null ? evt.srcElement : evt.target;
     var div = el.parentNode;
     var cont = document.getElementById(parentId);      
     if(cont.removeChild(div) == null){
      return false;
     }
     return true;
  }
  
  function addOldFile(data){
   var str = '<div name="div' + data.name + '" ><a href="#" style="text-decoration:none;font-size:12px;color:red;" onclick="removeOldFile(event,' + data.id + ')">删除</a>'+
      '   ' + data.name +
      '</div>';
      document.getElementById('oldImg').innerHTML += str;
  }
  
  function removeOldFile(evt, id){
      //前端隐藏域,用来确定哪些file被删除,这里需要前端有个隐藏域
      $("#imgIds").val($("#imgIds").val()=="" ? id :($("#imgIds").val() + "," + id));
      var el = evt.target == null ? evt.srcElement : evt.target;
      var div = el.parentNode;
      var cont = document.getElementById('oldImg');   
      if(cont.removeChild(div) == null){
          return false;
      }
      return true;
  }
  
  function ajaxFileUploadImg(id){
   //获取file的全部id
   var uplist = $("input[name^=uploads]");
   var arrId = [];
   for (var i=0; i< uplist.length; i++){
    if(uplist[i].value){
     arrId[i] = uplist[i].id;
     alert(uplist[i].id);
    }
   }
   $.ajaxFileUpload({
       url:'${ctx}/file/imguploads',
       secureuri:false,
       fileElementId: arrId,  //这里不在是以前的id了,要写成数组的形式哦!
       dataType: 'json',
       data: {          //需要传输的数据
          },
       success: function (data){
        alert("成功!");
       },
       error: function(data){
        alert("失败!");
       }
     });
   }
      </script>
 </head>
 
  <body>
      <input type="button"  value="添加附件" onclick="createInput('more');" />
  <div id="more"></div>
     <input type="button" onclick="ajaxFileUploadImg('3')" value="上传">
  </body>
</html>

3.新增java文件

/**
  * ajax 上传多个附件文件的后台接收处理
  * @param multipartRequest
  * @param response
  * @throws Exception
  */
 @RequestMapping(method=RequestMethod.POST, value="/imguploads")
 public void imgUpload(
      MultipartHttpServletRequest multipartRequest,
      HttpServletResponse response) throws Exception {
      response.setContentType("text/html;charset=UTF-8");
      Map<String, Object> result = new HashMap<String, Object>();
     
      //获取多个file
      for (Iterator it = multipartRequest.getFileNames(); it.hasNext();) {
        String key = (String) it.next();
        MultipartFile imgFile = multipartRequest.getFile(key);
        if (imgFile.getOriginalFilename().length() > 0) {
          String fileName = imgFile.getOriginalFilename();
                                  //改成自己的对象哦!
          Object obj = new Object();
          //Constant.UPLOAD_GOODIMG_URL 是一个配置文件路径
          try {
            String uploadFileUrl = multipartRequest.getSession().getServletContext().getRealPath(Constants.UPLOAD_GOODIMG_URL);
            File _apkFile = saveFileFromInputStream(imgFile.getInputStream(), uploadFileUrl, fileName);
            if (_apkFile.exists()) {
              FileInputStream fis = new FileInputStream(_apkFile);
            } else
              throw new FileNotFoundException("apk write failed:" + fileName);
            List list = new ArrayList();
            //将obj文件对象添加到list
            list.add(obj);
            result.put("success", true);
          } catch (Exception e) {
            result.put("success", false);
            e.printStackTrace();
          }
        }
      }
  //    String json = new Gson().toJson(result,new TypeToken<Map<String, Object>>() {}.getType());
      JSONObject json = JSONObject.fromObject(result);
      response.getWriter().print(json);
    }

   //保存文件
    private File saveFileFromInputStream(InputStream stream, String path,
        String filename) throws IOException {
      File file = new File(path + "/" + filename);
      FileOutputStream fs = new FileOutputStream(file);
      byte[] buffer = new byte[1024 * 1024];
      int bytesum = 0;
      int byteread = 0;
      while ((byteread = stream.read(buffer)) != -1) {
        bytesum += byteread;
        fs.write(buffer, 0, byteread);
        fs.flush();
      }
      fs.close();
      stream.close();
      return file;
    }

 

总结 :大致我看了一下它的fileajaxupload.js基本上就做了一个form拼接提交的原理。没有什么。



已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [ajax] 推荐:

原生AJAX

- - Web前端 - ITeye博客
对象是ajax的基础,几乎所有的浏览器都支持他,只是创建方式不同,如IE5,IE6. 2、AJAX - 向服务器发送请求请求. 与 POST 相比,GET 更简单也更快,并且在大部分情况下都能用. 然而,在以下情况中,请使用 POST 请求:. 无法使用缓存文件(更新服务器上的文件或数据库). 向服务器发送大量数据(POST 没有数据量限制).

初识Ajax

- - CSDN博客推荐文章
Ajax(Asynchronous JavaScript and XMLS异步JavaScript和XML)(“阿贾克斯”)技术. 完成页面的局部刷新,从而提升操作性能. AJAX 不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的 Web 应用程序的技术. 依赖的核心对象:XMLHttpRequest.

jquery ajax 跨域请求

- - 博客园_首页
使用 jquery 中的ajax  进行跨域请求. 说明:dataType 为  "jsonp"  ;type 只能为 GET.                    //处理错误. 后台处理代码 ValidAccountsExists.aspx.

ajax核心js代码

- - ITeye博客
                         //针对firefox,mozillar,opera,safari,IE7,IE8.                          //针对某些特定版本的mozillar浏览器的bug进行修正.                          //针对IE6,IE5.5,IE5.

反向Ajax,第1部分:Comet介绍

- 茫茫 - 译言-每日精品译文推荐
来源Reverse Ajax, Part 1: Introduction to Comet. web开发在过去的几年中有了很大的进展,我们已经远超了把静态网页链接在一起的做法,这种做法会引起浏览器的刷新,并且要等待页面的加载. 现在需要的是能够通过web来访问的完全动态的应用,这些应用通常需要尽可能的快,提供近乎实时的组件.

ajax后退解决方案(一)

- We_Get - 博客园-首页原创精华区
一、使用iframe,通过document.write产生历史. . 点击按钮后更新页面DOM(模拟ajax提交),会发现浏览器后退按钮可用了. 这种方式缺点是只支持IE和Firefox. 作者: snandy 发表于 2011-09-18 08:42 原文链接.

反向Ajax,第2部分:WebSocket

- KnightE - 译言-电脑/网络/数码科技
来源Reverse Ajax, Part 2: WebSockets. 时至今日,用户期待的是可通过web访问快速、动态的应用. 这一文章系列展示了如何使用反向Ajax(Reverse Ajax)技术来开发事件驱动的web应用. 系列的第1部分介绍了反向Ajax、轮询(polling)、流(streaming)、Comet和长轮询(long polling).

一次Ajax查错的经历

- - 酷壳 - CoolShell.cn
我有一朋友做网站,用jQuery的Ajax方法从后端载入一段HTML代码然后动态插入到网页的Div元件中. jQuery强大的load方法可以完成这个事情. 在Chrome,Firefox,Safari下运行一点问题也没有,只有IE不行,不管是IE7,IE8,还是IE9. 问题的症壮是,使用IE访问那个Ajax的链接,没有问题,但是在jQuery的Ajax方法返回了“undefined”的respons对象.

ajax与HTML5 history pushState/replaceState实例

- - 张鑫旭-鑫空间-鑫生活
本文地址: http://www.zhangxinxu.com/wordpress/?p=3432. 我就TM想找个例子,知道如何个使用,使用语法什么的滚粗. 精力总是有限的,昨天一冲动,在上海浦东外环之外订了个90米的房子,要借钱筹首付、贷款和领证什么的. HTML5 history相关知识点啪啦啪啦讲起来也是一条又臭又长的裹脚布,精气神实在不够用,这里,直接一个实例.

一个简单的AJAX示例

- - 博客园_Ruby's Louvre
虽然现在有了框架,许多AJAX调用直接调用它们的API就可用. 但有些极端情况,比如面试,比如第三方应用不想加载这些库,我们就只有自己写. 这时想必有许多人要疯狂google,百度了. 网上太多垃圾信息,我还是在自己博客上保存一份吧.