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

    一. http协议规定:

      1. 必须使用POST方式提交请求;

      2. 在HTML页面表单中必须配置 enctype="multipart/form-data" (表示数据使用什么样的编码方式);

    另外,在HTML页面表单中必须使用 <input type="file">控件

    二. 基于SpringMVC的文件上传

    简易客户端:

    <form method="post" enctype="multipart/form-data" action="/upload">
        <h3>选择文件</h3>
        <input type="file" name="file" placeholder="请选择文件">
       <input type="submit" value="提交">
    </form>

    简易服务端:

    @PostMapping("/upload")
    public String upload(MultipartFile file) throws IOException {
        file.transferTo(new File("d:1.jpg"));
        return "OK";
    }

      1. 文件大小:默认上传大小是有限制的,如果服务端报FileSizeLimitExceededExceprion,说明是文件大小受限,如果需要自定义,就向SpringBoot容器中添加一个MultipartConfigElement对象

        在配置类中添加以下代码:

    @Bean
    public MultipartConfigElement multipartConfigElement(){
        MultipartConfigFactory multipartConfigFactory = new MultipartConfigFactory();
        // 设置文件上传最大限制为 5 M
        multipartConfigFactory.setMaxFileSize(DataSize.ofMegabytes(5));
        // 设置请求最大限制为 6 M
        multipartConfigFactory.setMaxRequestSize(DataSize.ofMegabytes(6));
        return multipartConfigFactory.createMultipartConfig();
    }

        注意:全局的上传限制和控制器中的文件上传限制应该同时存在

            全局的上传限制:自定义上传限制;拦截明显的错误(即明显超出大小限制)请求

            控制器上传限制:划分业务上传,根据业务不同自定义上传限制

      2. 关于文件可以使用api获取文件相关属性.如:

        3. 关于文件名称,在写入磁盘时,需要定义其文件名和扩展名,一些特殊文件只有文件名没有扩展名或者在Linux和MacOS中隐藏文件只有文件名而且是以点开头

        4. 上传是为了下载,所以,所有的文件上传的路径必须是可以通过hkttp访问到的位置,解决方法:

        1) 使用 HttpServletRequest 对象获取可访问的webapp路径(父级路径定位到request.gettServletContext().getRealPath("")),将其上传到webapp目录下.

          2) 使用SpringBoot或者SpringMVC自定义资源目录,http可以直接访问该资源目录

          在配置文件中添加以下配置

    spring.resources.static-locations[0] = file:e:/upload, 
    spring.resources.static-locations[1] = file:e:/img
    spring.resources.static-locations[2] = classpath:/static

          注意:

            ① 静态目录可以配置多个

            ② 配置时如果没有配置原静态目录(static目录),则该目录下的资源文件就不可用了,需要显式的配置

          进行上传时,只需要写入到该目录下,既可以通过http访问

        5. 文件类型

        使用contentType进行文件类型判断,只需要获取文件的类型,然后与允许类型进行比较即可,可以将文件类型创建为一个列表,调用contains方法判断即可

        6. 关于其他限制,如空判断,大小判断只需要调用相应的api进行判断即可

        7. 关于使用ajax异步请求的方式发送请求

        $.ajax({
            url: '/upload',
            type: 'POST',
            data: new FormData($("#form")[0]),
            processData: false,
            contentType: false,
            success: function (json) {
                // 处理响应
            }
        });

        注意:

          1)  enctype="multipart/form-data" 的form表单数据必须是FormData类型,传入该表单

          2) 上传文件的ajax请求必须配置processData: false和contentType: false这两项

          3) contentType在此处填false的原因是告诉ajax函数data数据已经处理过,不需要进行再处理

    三. 使用base64编码方式的上传(一般是图片)

      1. 客户端

         提交请求:

    $("#send").click(function () {
            var files = $('#background_pic')[0].files
            var file = files[0];
            var reader = new FileReader();
            reader.readAsDataURL(file);
            reader.onload = function (theFile) {
                var image = new Image();
                // 图片可以得到base64编码
                image.src = theFile.target.result;
            var img = image.src.replaceAll("%", "-")
    var data = { img: image.src } $.ajax({ url:'/upload', type: 'POST', data: data, dataType: 'json', success: function (json) { if(json.status != 200){ alert("上传图片失败!请稍后重试!"); }else { alert("上传成功!"); } } }) } });

        此外,使用种方式可以对图片在前端进行校验(校验内容自定义即可)

    function checkImg(files){
            var file = files[0];
            var fileTypes = [".jpg", ".png",".gif",".jpeg"];
            var filePath = file.name;
            var flag = false;
            if(filePath){
                var fileEnd = filePath.substring(filePath.indexOf("."));
                for (var i = 0; i < fileTypes.length; i++) {
                    if (fileTypes[i] == fileEnd) {
                        flag = true;
                        break;
                    }
                }
            }
            if (!flag){
                alert("请上传 jpg、png、jpeg 的图片格式文件!");
                $('#background_pic').val(null);
                return;
            }
            var reader = new FileReader();
            reader.readAsDataURL(file);
            var ret = [];
            reader.onload = function (theFile) {
                var image = new Image();
                image.src = theFile.target.result;
                //console.log(image.src);
                image.onload = function () {
                    width = this.width;
                    height = this.height;
                    console.log(width!=1920 + " and " + height!=1080)
                    if (width != 1920 || height != 1080) {
                        alert("为了更好的显示效果,请使用分辨率为1920×1080的图片!");
                        $('#background_pic').val(null);
                        return;
                    }
                };
            }
        }
    View Code

      2. 服务端

       @PostMapping("/upload")
        public String upload(String img){
            // 格式: data:image/jpeg;base64,{{具体内容的数据编码}}或者data:text/txt;base64,{{具体内容的数据编码}}等等
            // 传输过程中会将 + 替换为空格
            // 前端自定义将 % 替换为 -
            img = img.replaceAll(" ", "+");
            img = img.replaceAll("-", "%");
            String[] strArr = img.split(",");
            String dataType = strArr[0];
            String imgBase64 = strArr[1];
            String suffix = dataType.substring(dataType.indexOf("/"), dataType.indexOf(";"));
            String parent = "e:/img";
            String child = UUID.randomUUID().toString() + "." + suffix;
            File file = new File(parent, child);
            BASE64Decoder decoder = new BASE64Decoder();
    
            try {
                byte[] b = new byte[0];
                b = decoder.decodeBuffer(imgBase64);
                for (int j = 0; j < b.length; ++j) {
                    //调整异常数据
                    if (b[j] < 0) {
                        b[j] += 256;
                    }
                }
                OutputStream out = new FileOutputStream(file);
                out.write(b);
                out.flush();
                out.close();
            } catch (IOException e) {
                throw new RuntimeException("描述");
            }
            return "OK";
        }

     

  • 相关阅读:
    简单查询
    Scott用户表
    记一次Sqoop抽数据异常
    Flink+Druid构建实时OLAP的探索
    客户端埋点实时OLAP指标计算方案
    Kafka服务不可用(宕机)问题踩坑记
    实时计算-多级订单金额,及下级人数
    Apache Druid0.15.0安装方式
    superset安装文档
    Scala的常用小技巧
  • 原文地址:https://www.cnblogs.com/xiao-lin-unit/p/14583899.html
Copyright © 2011-2022 走看看