zoukankan      html  css  js  c++  java
  • Java文件上传

    参考帖子

    https://stackoverflow.com/questions/32160662/upload-multiple-files-with-formdata-using-angularjs-and-asp-net-mvc 

    <input type="file" id="file1" name="file1" multiple="multiple" />
    <input type="file" id="file2" name="file2" multiple="multiple" />
    <input type="file" id="file3" name="file3" multiple="multiple" />
    <input type="file" id="file4" name="file4" multiple="multiple" />
    <input type="file" id="file8" name="file8" multiple="multiple" />
    <input type="file" id="file9" name="file9" multiple="multiple" />
    //不需要包在form表单里面也可以
    //传输的方式在js中指定为multipart/form-data 即可
    //multiple="multiple"属性表示一个文件筐可以上传多个文件
    多文件异步上传的HTML代码
     console.log("-------#imgform-----"+JSON.stringify($("#imgform")));
                console.log("-------#imgform-----"+$("#imgform")[0]);
                console.log("-------#file1-----"+$("#file1")[0].files);
                /*var  fileForm = new FormData();
                fileForm.append("file1" , $("#file1")[0].files );
                fileForm.append("file2" , $("#file2")[0].files );
                fileForm.append("file3" , $("#file3")[0].files );
                fileForm.append("file4" , $("#file4")[0].files );
                fileForm.append("file8" , $("#file8")[0].files );
                fileForm.append("file9" , $("#file9")[0].files );*/
                 $http({
                    method : 'POST',
                    url : '/omss/uploadCheckImg',
                    data : 
                     {
                        file1: $("#file1")[0].files,
                        file2: $("#file2")[0].files,
                        file3: $("#file3")[0].files,
                        file4: $("#file4")[0].files,
                        file8: $("#file8")[0].files,
                        file9: $("#file9")[0].files,
                    },
                    header: {
                        'Content-Type': 'multipart/form-data'
                    },
                    transformRequest: function (data, headersGetter) {
                        var formData = new FormData();
                         formData.append("new_id",$scope.employee.id);
                        ///angular.forEach(data, function (value, key) {
                           // debugger;
                           // formData.append(key, value);
                           //var formData = new FormData();
                        //https://stackoverflow.com/questions/32160662/upload-multiple-files-with-formdata-using-angularjs-and-asp-net-mvc
                        for (var i = 0; i < data.file1.length; i++) {
                            formData.append("file1", data.file1[i]);
                           }
                        for (var i = 0; i < data.file2.length; i++) {
                            formData.append("file2", data.file2[i]);
                           }
                        
                        for (var i = 0; i < data.file3.length; i++) {
                            formData.append("file3", data.file3[i]);
                           }
                        for (var i = 0; i < data.file4.length; i++) {
                            formData.append("file4", data.file4[i]);
                           }
                        for (var i = 0; i < data.file8.length; i++) {
                            formData.append("file8", data.file8[i]);
                           }
                        for (var i = 0; i < data.file9.length; i++) {
                            formData.append("file9", data.file9[i]);
                           }
                           
                           
                        //});
                        var headers = headersGetter();
                        delete headers['Content-Type'];
                        return formData;
                    }
    //                transformRequest: function(data) {
    //                    var formData = new FormData();
    //                    for (var i = 0; i < data.files.length; i++) {
    //                        formData.append("files[" + i + "]", data.files[i]);
    //                    }
    //                   return formData;
    //                }
                     
                    //processData: false,
                   // contentType: false
                }).success(function(data, status, headers, config) { 
                    $scope.status = status;
                    console.log(data);    
                    //alert(data);
                }).error(function(data, status, headers, config) {
                    $scope.data = data || "Request failed";
                    $scope.status = status;
                    $scope.tips = '对不起,您的网络情况不太稳定。';
                });
    多文件异步上传的js代码
    import org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper;
    import org.springframework.web.multipart.commons.CommonsMultipartResolver;
    
    public String uploadCheckImg(HttpServletRequest request,
                HttpServletResponse res, String id) {
            String msgString1 = "";
            String msgString2 = "";
            String msgString3 = "";
            String msgString4 = "";
            String msgString5 = "";
            String msgString6= "";
            String msgString7 = "";
            String msgString8 = "";
            String msgString9 = "";
            // 解析器解析request的上下文
            CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
                    request.getSession().getServletContext());
            // 先判断request中是否包涵multipart类型的数据,
            if (multipartResolver.isMultipart(request)) {
                msgString1=writerImg1(request,"file1",id,"001");//写入身份证
                msgString2=writerImg1(request,"file2",id,"002");//写入毕业证
                msgString3=writerImg1(request,"file3",id,"003");//写入学位证
                msgString4=writerImg1(request,"file4",id,"004");//写入简历
                //msgString5=writerImg1(request,"file5",id,"005");//写入社保卡
                //msgString6=writerImg1(request,"file6",id,"006");//写入公积金
                //msgString7=writerImg1(request,"file7",id,"007");//写入银行卡
                msgString8=writerImg1(request,"file8",id,"008");//写入离职证明
                msgString9=writerImg1(request,"file9",id,"009");//写入个人头像
            }
            return msgString1 + msgString2 + msgString3 + msgString4+msgString5 + msgString6 + msgString7 + msgString8 + msgString9;
        
        }
    
    public String writerImg1(HttpServletRequest request,
                String inputname,String id, String fileType4){
            String fileTypeName="";
            switch(fileType4){
                case "001" :fileTypeName="身份证";break;
                case "002" :fileTypeName="毕业证";break;
                case "003" :fileTypeName="学位证";break;
                case "004" :fileTypeName="简历";break;
                case "005" :fileTypeName="社保卡";break;
                case "006" :fileTypeName="公积金";break;
                case "007" :fileTypeName="银行卡";break;
                case "008" :fileTypeName="离职证明";break;
                case "009" :fileTypeName="个人头像";break;
            }
            String msgString4="";
            String realPath = request.getSession().getServletContext()
                    .getRealPath("/")
                    + "img_file";// 取系统当前路径
            // 文件保存目录URL
            String saveUrl = request.getContextPath() + "/img_file";
            String[] fileTypes = new String[] { "jpeg", "jpg", "pdf", "doc",
                    "docx", "gif", "png", "htm", "html", "txt" }; // 定义允许上传的文件扩展名
            long maxSize = 1024000 * 10; // 允许最大上传文件大小
            MultiPartRequestWrapper multipartRequest = (MultiPartRequestWrapper) request;
            File[] files4 = multipartRequest.getFiles(inputname);
            if (files4 == null) {
    
            } else {
                for (int i = 0; i < files4.length; i++) {
    
                    // 得到上传文件的扩展名
                    String fileName = multipartRequest.getFileNames(inputname)[i];
                    String fileName1 = fileName.substring(0,
                            fileName.lastIndexOf("."));
                    String fileExt = fileName.substring(
                            fileName.lastIndexOf(".") + 1).toLowerCase();
    
                    File file = files4[i];
    
                    // 检查扩展名
                    if (!Arrays.asList(fileTypes).contains(fileExt)) {
                        msgString4 = msgString4 + fileTypeName+"—" + "上传文件扩展名是不允许的扩展名。<br>";
                    }
                    // 检查文件大小
                    if (file.length() > maxSize) {
                        msgString4 = msgString4 + fileTypeName+"—" + "上传文件大小超过限制。<br>";
                    }
                    // 检查目录写入权限
                    File uploadDir = new File(realPath);
                    if (!uploadDir.canWrite()) {
                        msgString4 = msgString4 + fileTypeName+"—" + "上传目录没有写入权限。<br>";
                    }
                    Date date = new Date();
                    SimpleDateFormat sdf = new SimpleDateFormat(
                            "yyyyMMddHHmmss");
                    String time = sdf.format(date);
                    String realDesc = realPath + "/" + fileType4 + "/"
                            + fileName1 + time + i + "." + fileExt;
                    String saveDesc = saveUrl + "/" + fileType4 + "/"
                            + fileName1 + time + i + "." + fileExt;
                    logger.info("-----绝对路径realDesc------" + realDesc);
                    if (file.renameTo(new File(realDesc))) {
                        // 将文件的映射关系写入数据库
                        db.insertCheckImg(id, fileName, fileType4, realDesc,
                                saveDesc);
                        msgString4 = msgString4 + fileTypeName+"—" + "[" + fileName + "]"
                                + "上传成功!<br>";
                    } else {
                        msgString4 = msgString4 + fileTypeName+"—" + "[" + fileName + "]"
                                + "上传失败!该文件已存在,请重新命名!<br>";
                    }
    
                }
            }
            return msgString4;
            
        }
    多文件异步上传的java后台代码

    本文转载自 文件上传与 Angular

    最近项目需要使用 Angular,对于初学 Angular 的我只能硬着头皮上了,项目中有一个需求是文件上传,磕磕绊绊之下也实现了,将实现过程中学习到的一些知识记录下来以备将来查阅。

    与表单数据编码相关的知识


    通常,我们使用 HTML 的标签 <form> 来为用户输入创建一个表单,使用 <input type="file"> 作为文件上传的控件。

    要将表单的数据发送给后台,不仅要通过指定 <form> 的属性 method 来确定发送数据的 HTTP 方法而且需要通过指定 <form> 的属性 enctype 来确定对发送数据的编码方式。

    下面对这两个属性进行简单说明。

    表单 form 的属性 method

    <form> 的属性 method 规定用于发送 form-data 的 HTTP 方法,其值可以为 get 或者 postget 请求会将表单的数据编码后以 name1=value1&name2=value2 的形式附加到请求的 url 后面进行发送。post 请求会将表单的数据进行编码之后置于请求体中进行发送。

    本文接下来的讨论主要基于 post 请求方式。

    表单 form 的属性 enctype

    <form> 标签的属性 entype 用来规定在发送表单数据之前应该如何对其进行编码,其实就是用来指定请求的编码类型。

    enctype属性有 3 个取值,在 w3school 中对于其取值的描述如下:

    取值描述
    application/x-www-form-urlencoded 空格转换为 "+" 加号,特殊符号转换为 ASCII HEX 值
    multipart/form-data 不对字符编码。在使用包含文件上传控件的表单时,必须使用该值
    text/plain 空格转换为 "+" 加号,但不对特殊字符编码

    其中 application/x-www-form-urlencoded 是默认采用的编码的方式,如果表单 <form> 中有用到文件上传的控件,就要手动指定编码为 multipart/form-data

    下面分别对上述这几种编码方式进行举例(均基于 post 请求方式)

    • 编码为 application/x-www-form-urlencoded 的情况

    首先,构造一个表单:

    <form method="post" action="/" enctype="application/x-www-form-urlencoded">
      <input type="text" name="name1" placeholder="name1">
      <input type="text" name="name2" placeholder="name2">
      <input type="submit">
    </form>

    在输入框内分别输入 i'm name1 和 name@2 ,根据编码规则,提交表单的时候,表单数据会被编码成 name1=i%27m+name1&name2=name%402 置于请求体中进行传递,在 chrome 浏览器中执行结果也正如预期所示。


    以 application/x-www-form-urlencoded 编码来发送的表单数据
    • 编码为 multipart/form-data 的情况

    编码为 multipart/form-data 的情况又有所不同,先来看看示例代码的结果。

    示例代码:

    <form method="post" action="/" enctype="multipart/form-data">
      <input type="text" name="name1" placeholder="name1">
      <input type="text" name="name2" placeholder="name2">
      <input type="file" name="inputfile">
      <input type="submit">
    </form>

    在输入框内分别输入 i'm name1 和 name@2 ,再选择一个名为 testfile.txt 的文件上传,可以在 chrome 中看到发送的请求如下:


    以 multipart/form-data 编码来发送的表单数据

    注意图片中的红框部分,Content-Type 值为 multipart/form-data; boundary=----WebKitFormBoundaryBdpfgMg4VKAZat6C ,其中多了一个叫做 boundary 的字段,它是由浏览器随机生成的一个字符串,作为表单数据的分割边界来使用的,在服务器端会根据这个 boundary 边界字段来解析表单数据。

    可以明显看到,以边界分割的每一段均对应于一项表单数据,每项数据均包含有一个 Content-Disposition 字段和一个 name 字段,而对于上传的文件则会多一个指定上传文件名字的 filename 的属性和上传文件的类型的 Content-Type 字段,由于例子中上传的文件是 .txt 格式的文件,因此 Content-Type 的值为 text/plain,有关文件的扩展名和 Content-Type 的对照表可以看这里

    • 编码为 text/plain 的情况
      这种情况与编码为 application/x-www-form-urlencoded 的情况类似,唯一的差别就在于 text/plain 不对特殊字符进行编码。

    文件上传的 Angular 实现


    基于 FormData 的实现

    实现的思路:通过 File API 获取控件中上传的文件,利用 FormData 类型构造表单数据上传。

    基本知识:File API 和 FormData 类型
    • File API

    File API(文件API)为Web 开发人员提供一种安全的方式来访问用户计算机中的文件,并更好地对这些文件执行操作。

    具体来讲,File API 在表单中的文件输入字段的基础上,又添加了一些直接访问文件信息的接口。HTML5 在 DOM 中为文件输入元素添加了一个 files 集合。在通过文件输入字段选择了一或多个文件时,files 集合中将包含一组 File 对象,每个 File 对象对应着一个文件。

    构造一个文件上传的表单,通过如下 jQuery 代码:

    $("input[type='file']")[0].files

    在 chrome 浏览器控制台中可以看到获得的信息如下:

    可以看到选取的文件 testfile.txt 的相关信息,因此可以通过上述方式来获得上传的文件。

    关于 File API 的更多叙述可以在这里获得。

    • FormData 类型

    FormData 是在 XMLHttpRequest Level 2 中定义的,为序列化表单以及创建与表单格式相同的数据(用于通过XHR 传输)提供了便利。

    下面这段对于 FormData 对象的描述引用自 MDN,更多关于 FormData 类型的叙述可以在这里获得。

    XMLHttpRequest Level 2 添加了一个新的接口 FormData. 利用FormData 对象,我们可以通过 JavaScript 用一些键值对来模拟一系列表单控件,我们还可以使用 XMLHttpRequest 的 send() 方法来异步的提交这个"表单". 比起普通的 ajax, 使用 FormData 的最大优点就是我们可以异步上传一个二进制文件.

    可见,我们可以使用 FormData 对象来模拟实现文件上传时候提交的表单数据,而构造提交的数据是通过 FormData 的方法 append() 实现的,它用于给当前 FormData 对象添加一个键/值对。

    Angular 实现

    有了上面所说的实现思路和基础知识,现在可以着手进行代码的实现了。

    • 首先,编写一个指令用来获取上传文件的 File 对象。

    代码如下:

    .directive( "fileModel", [ "$parse", function( $parse ){
      return {
        restrict: "A",
        link: function( scope, element, attrs ){
          var model = $parse( attrs.fileModel );
          var modelSetter = model.assign;
    
          element.bind( "change", function(){
            scope.$apply( function(){
              modelSetter( scope, element[0].files[0] );
              // console.log( scope );
            } )
          } )
        }
      }
    }])

    这个指令的使用方式如下:

    <input type="file" file-model="fileToUpload">

    对于 <input> 元素,在它们失去焦点且 value 值改变时会触发 change 事件,因此我们在指令的 link 函数中监听元素上的 change 事件,在事件响应函数中获取用户上传的文件信息,并且将该文件赋值给 $scope 对象中与指令 fileModel 绑定的属性(上例中为 fileToUpload)。

    可以运行例子中的代码,选择一个文件 filetest.txt,打印出赋值后的 $scope 对象如下:


    将获取的上传文件赋给 $scope 对象

    如红框所示,$scope 的属性 fileToUpload 即是上传的文件 filetest.txt 的信息。

    • 然后,编写一个服务用于发送上传文件的 multipart/form-data 请求。

    代码如下:

    .service( "fileUpload", ["$http", function( $http ){
      this.uploadFileToUrl = function( file, uploadUrl ){
        var fd = new FormData();
        fd.append( "file", file )
        $http.post( uploadUrl, fd, {
          transformRequest: angular.identity,
          headers: { "Content-Type": undefined }
        })
        .success(function(){
          // blabla...
        })
        .error( function(){
          // blabla...
        })
      }
    }])

    在服务 fileUpload 的方法 uploadFileToUrl 中,通过 FormData 的 append() 方法将上传的文件序列化为表单数据,然后通过 $http.post() 方法发送给后台。

    Angular 默认的 transformRequest 方法会尝试序列化我们的 FormData 对象,因此此处我们使用 angular.identity 函数来覆盖它;另外,angular 在发送 POST 请求的时候使用的默认 Content-Type 是 application/json,因此此处需要调整为 undefined,这时浏览器会自动的帮我们设置成 multipart/form-data 的编码方式,同时还会生成一个合适的 boundary,如果手动设置成 multipart/form-data 的话就不会生成 boundary 字段了。

    • 最后,在控制器的合适地方发送这个请求。

    现在我们已经获得了上传的文件的相关信息,也有一个用于发送该文件的服务,那么只要在控制器中定义一个用于发送的函数,然后在合适的时机调用它即可将文件上传到后台去了。

    举个例子,在控制器的 $scope 里面定义一个发送请求的函数 sendFile

    .controller( "myCtrl", [ "$scope", "fileUpload", function( $scope, fileUpload ){
      $scope.sendFile = function(){
        var url = "/server",
            file = $scope.fileToUpload;
        if ( !file ) return;
        fileUpload.uploadFileToUrl( file, url );
      }
    }])

    然后我们可以定义一个按钮,当用户点击这个按钮的时候就会将上传的文件发送出去。

    <button type="button" ng-click="sendFile()">Submit</button>

    结果是这样的:


    通过 FormData 上传文件的请求
    兼容性

    由于 FormData 只兼容 IE10+ ,因此上述方法也只是在 IE10+ 中可以使用。

    如果你的应用需要兼容 IE8 ,老老实实封装一个含有 iframe 的指令即可,请接着往下看。

    含有 iframe 的实现

    指令代码如下

    .directive( "iframeFileUpload", [function(){
      var inner = "<div>";
          inner +=    "<form action="/server" method="post" enctype="multipart/form-data" target="uploadIframe">";
          inner +=        "<input type="file" name="filename">";
          inner +=        "<input type="submit">";
          inner +=      "</form>";
          inner +=      "<iframe id="uploadIframe" name="uploadIframe" style="display:none"></iframe>";
          inner +=    "</div>";
      return{
        restrict: "A",
        template: inner,
        // or
        // templateUrl: "components/iframeFileUpload.html",
        replace: true,
        scope: {},
        link: function( scope, element, attrs ){
          // blabla...
        }
      }
    }])

    调用方式大概是这样的:

    <div iframe-file-upload></div>
  • 相关阅读:
    uva 11995 I Can Guess the Data Structure!
    poj 1981 Circle and Points
    hdoj 2149 Public Sale
    hdoj 2188 悼念512汶川大地震遇难同胞——选拔志愿者
    hdoj 1846 Brave Game
    vue 细节注意
    meta标签设置不缓存
    -webkit-overflow-scrolling
    ios上表单默认样式
    vue-cli项目上传到github预览问题
  • 原文地址:https://www.cnblogs.com/abc8023/p/7455685.html
Copyright © 2011-2022 走看看