精华内容
下载资源
问答
  • SpringMVC文件上传,多文件上传实例

    千次下载 热门讨论 2014-03-01 20:28:21
    在上一篇SpringMVC基础教程的源码基础上增加了文件上传,多文件上传
  • springmvc实现文件上传jar包

    千次下载 热门讨论 2015-04-03 00:41:42
    springmvc中实现文件上传所要用到的jar包
  • 这几天用到了UEDITOR的文件上传功能,但是UEDITOR自带的文件上传功能只能将文件上传到项目根目录.百度搜索也没有很多相关的资料,更关键的是没有相关的源代码. 所以今天把我自己实现的这部分代码上传,希望大家共同进步...
  • 文件上传下载需要的jar包 java文件上传下载 源码 http://blog.csdn.net/da_zhuang/article/details/8737618
  • js实现文件上传

    热门讨论 2013-04-09 14:06:14
    很棒的js文件上传源代码,上传稳定还有进度提示,需要使用commons-fileupload和commons-io.可以直接嵌入项目里面使用。
  • Java文件上传实例并解决跨域问题

    千次阅读 多人点赞 2021-09-03 20:06:44
    本文内容为Java文件上传实例并解决跨域问题,其中重点讲解了文件上传,MultipartFile接口的使用,配置nginx,以及解决文件上传跨域的问题

    Java文件上传实例并解决跨域问题

    目录

    了解MultipartFile接口

    文件上传业务代码

    Controller类

    Service类:写了具体的业务逻辑

    修改nginx配置,将文件存储到文件服务器中

    每次上传文件都会经过网关,必然会给网关带来很大的压力,那我们如何绕过网关呢?

    1.在网关中配置白名单 ,这样也会走网关,只是压力少了一点点

    2.在nginx做转发,当请求文件上传时,直接转到相应的服务

    解决上传文件出现跨域问题

    写配置类CorsFilter

    在nginx配置中配置请求实体大小


    在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传功能的实现。

    了解MultipartFile接口

    我们实现文件的上传用到了Spring-web框架中的 MultipartFile接口,MultipartFile接口的源码注释中说“MultipartFile接口是  在大部分请求中接收的上载文件的表示形式。”

    A representation of an uploaded file received in a multipart request.
    The file contents are either stored in memory or temporarily on disk. In either case, the user is responsible for copying file contents to a session-level or persistent store as and if desired. The temporary storage will be cleared at the end of request processing.

    常用方法如下表

    Method Summary
     byte[]获取文件的字节数组getBytes()
              Return the contents of the file as an array of bytes.
     String获取文件的类型getContentType()
              Return the content type of the file.
     InputStream获取文件的输入流getInputStream()
              Return an InputStream to read the contents of the file from.
     String获取文件名getName()
              Return the name of the parameter in the multipart form.
     String获取原始文件名(防止篡改文件类型)getOriginalFilename()
              Return the original filename in the client's filesystem.
     long获取文件的大小,以字节的形式)getSize()
              Return the size of the file in bytes.
     boolean判断文件是否为空isEmpty()
              Return whether the uploaded file is empty, that is, either no file has been chosen in the multipart form or the chosen file has no content.
     void将接收到的文件传输到给定的目标文件。transferTo(File dest)
              Transfer the received file to the given destination file.

    文件上传业务代码

    Controller类

    /**
     * @Author: 小小张自由
     * @Date: 2021/7/6 - 20:56
     * @Description: 文件上传
     * @version: 1.0
     */
    @Controller
    @RequestMapping("upload")
    public class UploadController {
    
        @Autowired
        private UploadService uploadService;
    
        @PostMapping("image")
        public ResponseEntity<String> uploadImage(@RequestParam("file") MultipartFile file){
           String url= this.uploadService.uploadImage(file);
           if (StringUtils.isBlank(url)){
               return ResponseEntity.badRequest().build();
           }
            return ResponseEntity.status(HttpStatus.CREATED).body(url);
        }
    }
    

    Service类:写了具体的业务逻辑

    /**
     * @Author: 小小张自由
     * @Date: 2021/7/6 - 21:01
     * @Description: 文件上传
     * @version: 1.0
     */
    @Service
    public class UploadService {
    
        //用于判断文件的类型,暂时只判断了“image/gif","image/jpeg”
        private static final List<String> CONTENT_TYPES= Arrays.asList("image/gif","image/jpeg");
    
        private static final Logger LOGGER= LoggerFactory.getLogger(UploadService.class);
    
        /**
         * 业务逻辑代码
         * @param file 文件的存储的url
         * @return
         */
        public String uploadImage(MultipartFile file) {
    
            String originalFilename = file.getOriginalFilename();
            //校验文件类型
            //方法一:截取字符串
            String afterLast = StringUtils.substringAfterLast(".", originalFilename);
            //方法二:使用getContentType方法
            String contentType = file.getContentType();
            if (!CONTENT_TYPES.contains(contentType)){
                LOGGER.info("文件类型不合法:"+originalFilename);
                return null;
            }
            //校验文件内容
            try {
                //获取文件流
                BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
                if (bufferedImage==null){
                    LOGGER.info("文件内容不合法:{}",originalFilename);
                    return null;
                }
                //保存到服务器   E:\Leyou\image
                //将接收到的文件传输到给定的目标文件。
                file.transferTo(new File("E:\\Leyou\\Image\\"+originalFilename));
                
                //返回URL,进行回显
                //可以使用Nginx-图片服务器
                return "http://image.leyou.com/"+originalFilename;
            } catch (Exception e) {
                LOGGER.info("服务器内部错误:"+originalFilename);
                e.printStackTrace();
            }
            return null;
        }
    }

    修改nginx配置,将文件存储到文件服务器中

    修改Nginx的配置文件nginx.conf,监听80端口,设置root的值为:E盘

    - 图片不能保存在服务器内部,这样会对服务器产生额外的加载负担
    - 一般静态资源都应该使用独立域名,这样访问静态资源时不会携带一些不必要的cookie,减小请求的数据量

    server {
            listen       80;
            server_name  image.leyou.com;
    
            proxy_set_header X-Forwarded-Host $host;
    		proxy_set_header X-Forwarded-Server $host;
    		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    		
    		location / {
    			root E:\\Leyou\\image;
    		}
        }

    每次上传文件都会经过网关,必然会给网关带来很大的压力,那我们如何绕过网关呢?

    1.在网关中配置白名单 ,这样也会走网关,只是压力少了一点点

    @Slf4j
    public class AuthorizeFilter implements GlobalFilter, Ordered {
    
        //白名单:存放放行的URL
        private List<String> allowPaths;
    
    
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
           
            //获取请求的url路径
            String path = request.getURI().getPath();
            boolean flag=isAllowPath(path);
            if (flag) {
                log.info("请求在白名单中,leyou.filter: {}",path);
                //放行
                return chain.filter(exchange);
            } else {
              //写其他的业务逻辑
                ~~~~
                
            }
        }
    
        private boolean isAllowPath(String path) {
         
              //判断是否允许放行
             if (allowPaths.contains(path)){
                 return true;
             }
             return  false;
    
      }

    2.在nginx做转发,当请求文件上传时,直接转到相应的服务

    本实例使用了方法二、需要增加配置

    	server {
            listen       80;
            server_name  api.leyou.com;
    
            proxy_set_header X-Forwarded-Host $host;
    		proxy_set_header X-Forwarded-Server $host;
    		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    		# 新增加的配置,用于文件上传
    		location /api/upload {
    			proxy_pass http://127.0.0.1:8082;
    			proxy_connect_timeout 600;
    			proxy_read_timeout 600;
    			
    			rewrite "^/api/(.*)$" /$1 break;
    		}
    		# 网关的配置
    		location / {
    			proxy_pass http://127.0.0.1:10010;
    			proxy_connect_timeout 600;
    			proxy_read_timeout 600;
    		}
        }

    当这样配置之后,文件上传就不会过网关,减少了网关的压力。但是有引来了一个新问题那就是跨域。

    解决上传文件出现跨域问题

    由于Nginx将文件上传的请求直接转发到了具体服务中,不再走gateway,所以gateway中的跨域配置,不再生效了。 需要在文件上传这个服务中单独配置跨域。

    写配置类CorsFilter

    /**
     * @Author: 小小张自由
     * @Date: 2021/6/15 - 11:12
     * @Description: 解决 跨域问题
     * @version: 1.0
     */
    @Configuration
    public class LeyouCorsConfiguration {
    
        @Bean
        public CorsFilter corsFilter(){
            //初始化配置对象
            CorsConfiguration configuration = new CorsConfiguration();
            //允许跨域访问的域名
            configuration.addAllowedOrigin("*");
           // configuration.setAllowCredentials(true);  //运行携带cookie
            configuration.addAllowedMethod("*"); //代表所有请求方法
            configuration.addAllowedHeader("*"); //允许携带任何头信息
    
            //初始化cors配置源对象
            UrlBasedCorsConfigurationSource configurationSource=new UrlBasedCorsConfigurationSource();
            configurationSource.registerCorsConfiguration("/**",configuration);
    
            //返回CorSfilter实例,参数
            return new CorsFilter(configurationSource);
        }
    
    }

    到此应该就可以上传了,但是还是报跨域,我已经配置好了啊,为什么还是报跨域呢?

    在nginx配置中配置请求实体大小

    我就想是不是Nginx的问题,然后我就一行一行的读配置,最后发现

    nginx配置中没有配置请求实体大小

    image.png

    加上这行配置就好了

    client_max_body_size 1024m;

    如果本篇博客对您有一定的帮助,大家记得留言+点赞+收藏哦。 

    展开全文
  • easyUI文件上传

    千次下载 热门讨论 2013-07-10 20:30:44
    基于easyui上传 支持大型文件 多文件上传 希望用到的朋友 不要忘记评价
  • ssm+文件上传+json

    2016-01-17 03:14:00
    spring4.24+springMVC+mybatis3.23+文件上传+json所需要的所有jar
  • Android文件上传.rar

    千次下载 热门讨论 2014-04-15 20:16:52
    此为博客例子代码,详细讲解请参考:http://blog.csdn.net/lmj623565791/article/details/23781773 有问题博客中留言
  • 俺亲手写的: 1.支持多文件上传 2.带进度条 3.可以显示文件名称 4.可以实时显示已上传的大小 5.可以从队列中删除 6.各元素的样式都可以自己控制
  • 1、首先将文件上传到服务器, 2、将文件传到数据库 3、上传完成后,删除文件
  • 文件上传漏洞

    万次阅读 多人点赞 2019-03-04 00:27:45
    文件上传漏洞 文件上传漏洞是指由于程序员未对上传的文件进行严格的验证和过滤,而导致的用户可以越过其本身权限向服务器上上传可执行的动态脚本文件。这里上传的文件可以是木马,病毒,恶意脚本或者WebShell等。...

    文件上传漏洞

    文件上传漏洞是指由于程序员未对上传的文件进行严格的验证和过滤,而导致的用户可以越过其本身权限向服务器上上传可执行的动态脚本文件。这里上传的文件可以是木马,病毒,恶意脚本或者WebShell等。这种攻击方式是最为直接和有效的,“文件上传”本身没有问题,有问题的是文件上传后,服务器怎么处理、解释文件。如果服务器的处理逻辑做的不够安全,则会导致严重的后果。

    在了解文件上传漏洞之前先了解什么是Web容器、IIS、文件解析。

    什么是web容器?
    web容器是一种服务程序,在服务器一个端口就有一个提供相应服务的程序,而这个程序就是处理从客户端发出的请求,如tomcat、apache、nginx等等。(可以理解为给编程语言提供环境)

    中间件:提供系统软件和应用软件之间连接的软件,以便于软件各部件之间的沟通。中间件处在操作系统和更高一级应用程序之间。

    容器*:给处于其中的应用程序组件(ASP,JSP,PHP)提供一个环境。使处于其中的应用程序组件之间跟容器中的环境变量接口交互,不必关注其他系统问题。

    服务器:www服务器或http服务器。提供web信息游览服务。它只需支持http协议、html文档格式以及url,向游览器提供服务的程序。

    什么是IIS?
    IIS全称是互联网信息服务,包括FTP/FTPS、NNTP、HTTP/HTTPS、SMTP等服务。

    .net Framework是基础类库,是程序运行的底层框架。

    IIS是架设Web服务器用来提供网页游览服务的,属于系统环境。

    一般用ASP.NET开发软件,然后靠IIS对公网提供服务。

    什么是文件解析?

    当服务器接收到一个HTTP请求的时候,IIS首先需要决定如何去处理这个请求(服务器处理.aspx和.html肯定是不一样的),根据的是文件的后缀名。

    服务器获取所请求的页面(也可以是文件)的后缀名后接下来会在服务器端寻找可以处理这类后缀名的应用程序,如果IIS找不到可以处理此类文件的应用程序,那么IIS将直接把这个文件返还给客户端。

    1 解析漏洞

    攻击者在利用上传漏洞时,通常会与Web容器的解析漏洞配合在一起。所以我们首先来了解一下解析漏洞,这样才能更深入地了解上传漏洞,并加以防范。
    常见的Web容器有ⅡS、Apache、Nginx、Tomcat等,下面主要讲IIS、Apache容器。
    1.1 IIS解析漏洞

    IIS 6.0在解析文件时存在以下两个解析漏洞。

    1. 当建立*.asa、*.asp格式的文件夹时,其目录下的任意文件都将被IIS当做asp文件来解析。

      例如:建立文件夹parsing.asp,在parsing.asp文件夹内新建一个文本文档test.txt,其内容为<%=NOW()%>,然后在浏览器内访问。
      “NOWO”是ASP提供获取当前时间的函数,TXT是文本文档格式,IIS是不会去解析此类文件的,应该会直接显示其内容,而在parsing.asp文件夹中,却被当作ASP脚本来解析。

    2. 当文件为*.asp;1.jpg时,IIS6.0同样会以ASP脚本来执行,如:新建文件test.asp;1.jpg,内容为<%=NOW()%>。

    1.2 Apache解析漏洞

    Apache是从右到左开始判断解析,如果为不可识别解析,就再往左判断,如xxx.php.owf.rar ,”.owf”和”.rar”这两种后缀是apache解析不了的,apache就会把xxx.php.owf.rar解析成php。

    怎么去判断是不是合法的后缀就是这个漏洞利用关键,测试时把常见的后缀都写上,去测试是不是合法,任意不识别的后缀,逐级向上识别。

    有些程序开发人员在上传文件时,判断文件名是否是PHP、ASP、ASPX、ASA、CER、ASPX等脚本扩展名,如果是,则不允许上传,这时攻击者就有可能上传1.php.rar等扩展名来绕过程序检测,并配合解析漏洞,获取到WebShell。

    2 绕过上传漏洞

    绕过上传漏洞分以下两种。

    客户端检测:客户端使用JavaScript检测,在文件未上传时,就对文件进行验证;

    服务器端检测:服务端脚本一般会检测文件的MIME类型,检测文件扩展名是否合法,
    甚至有些程序员检测文件中是否嵌入恶意代码。

    在研究上传漏洞之前,首先来看两个小工具:中国菜刀和一句话图片木马。
    “中国菜刀”这款软件是用来管理网站文件的,非常小巧灵活,它仅仅需要一段简短的代码
    就可以方便地管理网站。中国菜刀现在已经成为安全研究者手中必备的利器,其官方网站为:http://www.maicaidao.com

    该软件提供的服务器端文件仅有一行代码。目前支持的服务器端脚本包括:PHP、ASP、ASP.NET、JSP等,并且支持HTTPS安全连接的网站。常见的代码如下:

    Asp一句话:<%eval request(“xxx”)%>
    Php 一句话:<%php @eval($_POST[xxx]);?>
    Aspx一句话:<%@ Page Languag=”xxx”%><%eval(Request.Item[“xxx”])%>

    正因为代码短小精悍,所以被黑客称为一句话木马(一句话后门)。
    <?php @eval(S_POST['xxx']);?>保存为shell.php,上传至PHP主机空间中,配置菜刀进行连接,如图所示。
    在这里插入图片描述

    “图片一句话”则是将一句话木马插入在图片文件中,而且并不损坏图片文件,这一方法可以躲过少许的防火墙检测。制作图片一句话木马的方法非常多,目前已经有安全研究人员设计出了专业的制作软件:Edjpgcom。Edjpgcom的使用方法非常简单:把一张正常的图片拖到Edjpgcom.exe程序中,填写相应的一句话代码,就可以制作图片一句话木马。
    在插入一句话木马之后,以文本的方式打开图片,就可以看到一句话木马代码就在里面,而且不影响图片正常预览。
    还有将一句话木马与正常图片通过CMD命令结合起来。

    在这里插入图片描述
    在这里插入图片描述
    注:如果直接以文本的方式打开图片插入一句话,可能会造成文件损坏。

    知道了程序员是如何防护上传漏洞及一句话图片木马后,下面深入研究攻击者是如何绕过程序员的防护思维来上传一句话木马文件的。

    2.1 客户端检测

    2.1.1 使用FileBug浏览器插件

    FireBug是一款开源的浏览器插件,它支持Firefox、Chrome等浏览器。它可以让Web开发者轻松地调试HTML、JavaScript、AJAX、CSS等前端脚本代码,属于Web开发人员的必备武器。正由于FireBug功能强大,所以也被黑客认为是必备利器。

    2.1.2 中间人攻击

    中间人攻击这种方式与FireBug完全不同,FireBug是删除客户端的JavaScript验证,而使用Burp Suite则是按照正常的流程通过JavaScript验证,然后在传输中的HTTP层做手脚。
    首先把木马文件扩展名改为一张正常图片的扩展名,比如JPG扩展名,在上传时使用Burp Suite拦截上传数据,再将其中的扩展名JPG修改为PHP,就可以绕过客户端验。

    2.2 服务器端检测

    2.2.1 白名单与黑名单验证

    (1)黑名单过滤方式
    黑名单过滤是一种不安全的方式,黑名单定义了一系列不安全的扩展名,服务器端在接收文件后,与黑名单扩展名对比,如果发现文件扩展名与黑名单里的扩展名匹配,则认为文件不合法。

    (2)白名单过滤方式
    白名单的过滤方式与黑名单恰恰相反,黑名单是定义不允许上传的文件扩展名,而白名单则是定义允许上传的扩展名,白名单拥有比黑名单更好的防御机制。如:$WhiteList=
    array(rar’,jpg’,png,bmpy,gif,jpg;doc);在获取到文件扩展名后对 WhiteList数组里的扩展名迭代判断,如果文件扩展名被命中,程序将认为文件是合法的,否则不允许上传。

    2.2.2 MIME验证

    MIME类型用来设定某种扩展名文件的打开方式,当具有该扩展名的文件被访问时,浏览器会自动使用指定的应用程序来打开。如GIF图片MIME为image/gif,CSS文件MIME类型为text/ess。

    2.2.3.目录验证

    在文件上传时,程序通常允许用户将文件放到指定的目录中,然而有些Web开发人员为了让代码更“健壮”,通常会做一个操作,如果指定的目录存在,就将文件写入目录中,不存在则先建立目录,然后写入。

    2.2.4截断上传攻击

    文件名后缀有一个%00字节,可以截断某些函数对文件名的判断。在许多语言函 数中,处理字符串的函数中0x00被认为是终止符

    例如: 网站上传函数处理xxx.asp%00.jpg时,首先后缀名是合法的jpg格式,可以 上传,在保存文件时,遇到%00字符丢弃后面的 .jpg,文件后缀最终保存的后缀 名为xxx.asp

    3 文件上传漏洞防御

    首先,上传的文件能够被Web容器解释执行。所以文件上传后所在的目录要是Web容器所覆盖到的路径。 其次,用户能够从Web上访问这个文件。如果文件上传了,但用户无法通过Web访问,或者无法得到Web容器解释这个脚本,那么也不能称之为漏洞。 最后,用户上传的文件若被安全检查、格式化、图片压缩等功能改变了内容,则也可能导致攻击不成功。
    防范文件上传漏洞常见的几种方法:

    1.文件上传的目录设置为不可执行
    只要web容器无法解析该目录下面的文件,即使攻击者上传了脚本文件,服务器本身也不会受到影响,因此这一点至关重要。

    2.判断文件类型
    在判断文件类型时,可以结合使用MIME Type、后缀检查等方式。在文件类型检查中,强烈推荐白名单方式,黑名单的方式已经无数次被证明是不可靠的。此外,对于图片的处理,可以使用压缩函数或者resize函数,在处理图片的同时破坏图片中可能包含的HTML代码。

    3.使用随机数改写文件名和文件路径
    文件上传如果要执行代码,则需要用户能够访问到这个文件。在某些环境中,用户能上传,但不能访问。如果应用了随机数改写了文件名和路径,将极大地增加攻击的成本。再来就是像shell.php.rar.rar和crossdomain.xml这种文件,都将因为重命名而无法攻击。

    4.单独设置文件服务器的域名
    由于浏览器同源策略的关系,一系列客户端攻击将失效,比如上传crossdomain.xml、上传包含Javascript的XSS利用等问题将得到解决。

    5.限制上传文件大小
    限制上传文件的大小,防止由于内存、磁盘耗尽造成的拒绝服务。
    可以配置web server允许的最大Post大小。
    可以在代码层面获取上传文件的大小,根据文件类型的不同进行进一步的过滤。

    6.确保上传文件被访问正确返回
    1.将文件上传目录设置为静态资源目录,防止被解析为脚本执行。
    2.使用代理页面隐藏文件真实路径。
    3.使用上述方法时,确保Content-Type与实际文件类型一致。
    4.如果文件不允许在页面展示,仅允许下载,请设置Content-disposition:attachment。

    展开全文
  • 通用文件上传设计

    千次阅读 2018-12-21 15:47:36
    前端采用XMLHttpRequest进行文件上传。后端(springboot2.x)接口支持多文件同时上传,接口可根据数据库动态配置验证(文件大小、文件类型)合法性,该接口可满足上传文件大小500mb的需求(大于50...

    1.问题描述

    18年初跳槽来到新公司,在开发中惊奇的发现公司项目中的文件上传功能竟然存在好几个版本,他们为每个需要文件上传的业务实现了接口,仔细看了下这些上传文件代码,他们主要区别在于每个业务存储的文件类型、文件大小、是否要压缩需要限制或者是文件路径需要指定不同。这几个特性完全可以配置化解决问题(上家公司就是这么做的,配置化实现公用文件上传接口是一个正确的选择)。究其原因可能大家害怕更改之前的接口会照成bug,索性自己重写一个上传接口(反正是复制粘贴过来改下内容吧)。

    那么文件上传如何通过配置化实现公用呢?下面直接进入主题

    技术与接口定义

    后端服务我们直接使用springboot2.X框架,文件上传相关配置信息将入数据库,这样可支持动态修改。测试用例我提供一个html页面,或者你可以直接使用postman。更详细的内容处理请看代码(实现很简单的)

    api信息:
    接口地址:http://127.0.0.1:8080/uploadFile
    请求格式:post | multipart/form-data;

    参数名必填/类型说明
    bizType是/String不同业务对应不同的类型,根据此类型查找文件上传的配置
    bizId否/Long业务id,可以通过该id找到对于的业务信息
    isShrink否(默认false)/boolean是否需要压缩代码为了简介,暂未实现支持是否压缩
    file文件信息,支持多文件上传

    返回列表 JSON: [FileInfo]

    2.数据库设计

    文件信息配置表 file_conf , 不同业务对应不同的配置,这里主要考虑了文件类型、文件大小、文件存储路径等

    字段类型约束说明
    idint(11)必填自增主键id
    bize_typevarchar(20)必填业务类型,不同业务不同的类型
    file_type_limitvarchar(200)非必填允许上传的文件类型(mine-type标准),为空时不限制类型
    file_size_limitvarchar(20)非必填允许上传的文件大小(kb),为空时不限制大小
    pathvarchar(50)必填服务器存储文件的路径
    descriptionvarchar(100)非必填描述,如描述该业务类型对应的文件上传业务功能的业务表
    resource_realmvarchar (100)必填外部访问文件资源相对根路径
    enabledtinyint(4)必填是否可用(默认1可用,0禁用),用于禁止某个业务上传文件的功能
    creat_timedatetime必填创建时间
    last_update_timedatetime非必填最近修改时间

    文件信表 file_info ,主要作用保存文件存储的相关信息,方便某些业务需要统计上传文件或删除文件时需要

    字段类型约束说明
    idint(11)必填自增主键id
    bize_typevarchar(20)必填业务类型
    bize_idint(11)非必填业务id
    original_namevarchar (255)必填文件原名称
    new_namevarchar(50)必填(唯一)文件新名称(随机码
    file_typevarchar(20)必填文件类型
    file_sizevarchar(20)必填文件大小(kb)
    file_pathvarchar(200)必填文件服务器存储绝对路径
    relative_pathvarchar(200)必填文件相对路径,域名+此字段为该资源的请求地址
    creat_timedatetime必填创建时间
    last_update_timedatetime非必填最近修改时间
    del_flagtinyint(1)必填逻辑删除(默认0正常,1文件已被物理删除)

    3.主要代码实现

    3.1.model

    对应数据库表结构建立对应实体类

    /**
     * 文件配置信息</p>
     * table: file_conf
     * @author lilee
     * @version 1.0.0
     * @date 2018/12/20 14:55
     */
    public class FileConf {
        private Long id;  // 主键ID
        private String bizType;  // 上传服务类型
        private String fileTypeLimit; // 文件类型(mine-type标准),为空不限制上传类型
        private String fileSizeLimit; //(kb)文件限制大小,为空不限制上传大小(但要满足框架支持的上传文件大小)
        private String path; // 服务器文件夹路径
        private String description;  // 描述
        private String resourceRealm; // 访问资源路径
        private Boolean enabled; // 是否可用(默认1可用,0禁用)
        private Date createTime;  // 创建时间
        private Date lastUpdateTime;  // 最后修改时间
       
        // setter & getter
    }
    
    /**
     * 文件信息</p>
     * table: file_info
     * @author lilee
     * @version 1.0.0
     * @date 2018/12/20 14:55
     */
    public class FileInfo {
        private Long id;  // 主键ID
        private String originalName;  // 文件原名称
        private String newName; // 文件新名称
        private String fileType;  // 文件类型(image/jpg, image/png, video/mp4, xsl,doc等)
        private String fileSize; // 文件大小(kb)
        private String filePath;  // 文件服务器存储路径
        private String relativePath;  // 文件相对路径
        private Long bizId;  // 业务ID
        private String bizType;  // 上传服务类型(业务类型)
        private Date createTime;  // 创建时间
        private Date lastUpdateTime;  // 最后修改时间
        private Boolean delFlag; // 数据删除标记0=正常,1=文件已物理删除
    	
    	// setter & getter
    
    

    3.2.dao

    dao层,本实例为了简单,并未提供数据库操作相关代码,该模块需要用户根据自己项目架构自己实现
    当前文件存储到/home/data下

    @Repository
    public class FileConfDao {
    	// 根据业务类型bizType获取该业务的配置信息
        public FileConf selectByBizType(String bizType) {
            // todo 为了简单,未正真的对数据库操作 
        	// FileConf fileConf = dbdao.findByBizType(bizType);
            FileConf fileConf = new FileConf();
            fileConf.setBizType(bizType);
            fileConf.setPath("/home/data");
            fileConf.setResourceRealm("/res");
            fileConf.setEnabled(true);
            return fileConf;
        }
    	// 存储文件的信息
         public FileInfo insert(FileInfo fileInfo) {
           //  dbdao.insert(fileInfo)
            return fileInfo;
        }
    }
    

    3.3.service

    该模块实现文件上传主体,主要包括对文件参数信息验证,对文件上传是否符合业务的配置验证

    /**
     * TODO 文件上传service
     *
     * @author lilee
     * @version 1.0.0
     * @date 2018/12/20 14:55
     */
    @Service
    public class FileUploadService {
    
        @Resource
        private FileConfDao fileConfDao;
    
        // @Resource
        // private FileInfoDao fileInfoDao;
    
        protected static Logger log = LoggerFactory.getLogger(FileUploadService.class);
    
        /**
         * 文件上传
         * @param mpfList  文件信息集
         * @param bizType 业务类型(必传)
         * @param bizId   业务id
         * @param extraPath  额外的路径,首部和结尾不能带斜杠'/'
         * @return
         */
        public List<FileInfo> uploadFile(List<MultipartFile> mpfList, String bizType, Long bizId, String extraPath) {
            // 验证数据begin
            // 获取对应业务文件配置信息
            FileConf fileConf = this.fileConfDao.selectByBizType(bizType);
            if(fileConf == null){
                log.info("file conf is null");  // 打印文件配置信息
                return null;
            }
            // 验证文件信息是否符合配置信息
            if (!validateFileInfo(mpfList, fileConf)) {
                // 验证失败
                log.info("fileInfo is error");  // 打印文件配置信息
                return null;
            }
            // 信息验证end
    
            List<FileInfo> files = new ArrayList<>();
            FileInfo fileInfo = null;
            String path = fileConf.getPath();  // 文件存储的目录
            // 获取相对路径,由file_conf、额外路径
            String relativePath = fileConf.getResourceRealm() + "/"
                    + (StringUtils.isEmpty(extraPath) ? "" : extraPath + "/");
    
            // 验证服务器存储路径是否存在,若不存在,则新建文件夹
            File serFile = new File(path + relativePath);
            if (!serFile.exists()) {
                serFile.mkdirs();
            }
    
            // 循环上传文件
            for (MultipartFile mpf : mpfList) {
                String originalFileName = mpf.getOriginalFilename(); // 获取源文件名
                // 生成新文件名
                String newFileName = "F" + UUID.randomUUID().toString().replace("-", "").toUpperCase()
                        + originalFileName.substring(originalFileName.lastIndexOf("."));
                // 组装数据
                fileInfo = new FileInfo();
                fileInfo.setOriginalName(originalFileName);
                fileInfo.setFileSize(String.valueOf(mpf.getSize() / 1024)); // 单位(kb)
                fileInfo.setFileType(mpf.getContentType());     // 文件类型
                fileInfo.setNewName(newFileName);                        // 文件新名字
                fileInfo.setRelativePath(relativePath + newFileName);    // 文件相对路径
                fileInfo.setFilePath(path + relativePath + newFileName); // 文件物理路径
                fileInfo.setBizType(bizType);
                fileInfo.setBizId(bizId);
                fileInfo.setDelFlag(false);
                // 存储文件并记录到数据库
                try {
                    FileCopyUtils.copy(mpf.getBytes(), new FileOutputStream(fileInfo.getFilePath()));
                    fileConfDao.insert(fileInfo); 
                } catch (IOException e) {
                    log.error("upload file error!", e);
                    return null;
                }
                files.add(fileInfo);
            }
            return files;
        }
    
        private boolean validateFileInfo(List<MultipartFile> mpfList, FileConf fileConf) {
            if (mpfList == null || fileConf == null) { return false; }
            for (MultipartFile mpf : mpfList) {
                // 验证文件大小是否超出配置大小
                if (!StringUtils.isEmpty(fileConf.getFileSizeLimit()) && mpf.getSize() / 1024 > Integer.parseInt(fileConf.getFileSizeLimit())) {
                    return false;
                }
                // 验证文件类型是否符合文件配置的要求
                if (!StringUtils.isEmpty(fileConf.getFileTypeLimit()) && fileConf.getFileTypeLimit().indexOf(mpf.getContentType()) < 0) {
                    return false;
                }
            }
            return true;
        }
    }
    
    

    3.4.controller

    ****简单controller****

    @RestController
    public class FileUploadController {
        @Resource
        private FileUploadService fileUploadService;
    
        /**
         * 文件上传接口
         * @param request  
         * @param bizType 业务类型(必传)
         * @param bizId   业务id
         * @param extraPath  额外的路径,首部和结尾不能带斜杠'/'
         * @return
         */
        @RequestMapping(value ="/uploadFile", method = RequestMethod.POST)
        public List<FileInfo> uploadFile(MultipartHttpServletRequest request, String bizType, Long bizId, String extraPath) {
            int count = 0;
            List<FileInfo> result = this.fileUploadService.uploadFile(request.getMultiFileMap().get("fileData"), bizType, bizId, extraPath);
            return result;
        }
    }
    

    3.5.html测试代码

    使用postman更简单哦,记得考虑跨越问题
    引用博客https://www.cnblogs.com/tianyuchen/p/5594641.html

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
        <title>fileUpload Test</title>
        <script type="text/javascript">
            var xhr;
            var ot;//
            var oloaded;
            //上传文件方法
            function upladFile() {
                var url = "http://127.0.0.1:8080/uploadFile"; // 接收上传文件的后台地址 
                
                var form = new FormData(); // FormData 对象
    			var fileObj = document.getElementById("file").files; // js 获取文件对象
    			if (fileObj != null) {
    				for (var i=0; i< fileObj.length; i++) {
    					form.append('fileData', fileObj[i], fileObj[i].name);
    				}
    			}
                xhr = new XMLHttpRequest();  // XMLHttpRequest 对象
                xhr.open("post", url, true); //post方式,url为服务器请求地址,true 该参数规定请求是否异步处理。
                xhr.onload = uploadComplete; //请求完成(成功)
                xhr.onerror =  uploadFailed; //请求失败
                xhr.upload.onprogress = progressFunction;		//【上传进度调用方法实现】
                xhr.upload.onloadstart = function(){			//上传开始执行方法(初始)
                    ot = new Date().getTime();   				//设置上传开始时间
                    oloaded = 0;								//设置上传开始时,以上传的文件大小为0
                };
                xhr.send(form); 
            }
            //上传进度实现方法,上传过程中会频繁调用该方法
            function progressFunction(evt) {
                 var progressBar = document.getElementById("progressBar");
                 var percentageDiv = document.getElementById("percentage");
                 // event.total是需要传输的总字节,event.loaded是已经传输的字节。如果event.lengthComputable不为真,则event.total等于0
                 if (evt.lengthComputable) {		
                     progressBar.max = evt.total;
                     progressBar.value = evt.loaded;
                     percentageDiv.innerHTML = Math.round(evt.loaded / evt.total * 100) + "%";
                 }
                
                var time = document.getElementById("time");
                var nt = new Date().getTime();//获取当前时间
                var pertime = (nt-ot) / 1000; //计算出上次调用该方法时到现在的时间差,单位为s
                ot = new Date().getTime(); //重新赋值时间,用于下次计算
                
                var perload = evt.loaded - oloaded; //计算该分段上传的文件大小,单位b       
                oloaded = evt.loaded;//重新赋值已上传文件大小,用以下次计算
            
                //上传速度计算
                var speed = perload / pertime; //单位b/s
                var bspeed = speed;
                var units = 'b/s';//单位名称
                if(speed/1024 > 1){
                    speed /= 1024;
                    units = 'k/s';
                }
                if(speed/1024 > 1){
                    speed /= 1024;
                    units = 'M/s';
                }
                speed = speed.toFixed(1);
                //剩余时间
                var resttime = ((evt.total - evt.loaded) / bspeed).toFixed(1);
                time.innerHTML = ',速度:' + speed + units + ',剩余时间:' + resttime + 's';
    			if(bspeed == 0)
    			time.innerHTML = '上传已取消';
            }
            //上传成功响应
            function uploadComplete(evt) {
    			alert("上传成功!");
            }
            //上传失败
            function uploadFailed(evt) {
                alert("上传失败!");
            }
             //取消上传
            function cancleUploadFile(){
                xhr.abort();
            }
        </script>
    </head>
    <body>
        <progress id="progressBar" value="0" max="100" style="width: 300px;"></progress>
        <span id="percentage"></span><span id="time"></span>
        <br /><br />
        <input type="file" id="file" name="myfile" multiple="multiple"/>
        <input type="button" onclick="upladFile()" value="上传(多选)" />
        <input type="button" onclick="cancleUploadFile()" value="取消" />
    </body>
    </html>
    

    记得Application跨域解决:

    	@Bean
        public WebMvcConfigurer corsConfigurer() {
            return new WebMvcConfigurerAdapter() {
                @Override
                public void addCorsMappings(CorsRegistry registry) {
                    registry.addMapping("/**")
                            .allowedMethods("PUT", "DELETE","GET","POST")
                            .allowedHeaders("*")
                            .exposedHeaders("access-control-allow-headers",
                                    "access-control-allow-methods",
                                    "access-control-allow-origin",
                                    "access-control-max-age",
                                    "X-Frame-Options")
                            .allowCredentials(false).maxAge(3600);
                }
            };
        }
    

    4.最后

    上传文件的接口返回的url需要另外提供接口支持,可简单nginx配置代理文件资源。



    、﹗∕
    — 〇 -
    ╱︱ ヽ
    但行好事、莫问前程! 大家好、我是lilee
    _________________ *_*______
    ____ ____ ____
    展开全文
  • android带进度的文件上传

    千次下载 热门讨论 2013-01-06 14:09:54
    android带进度的文件上传
  • MinIO文件上传

    千次阅读 2020-09-21 00:10:16
    文章目录前言MinIO服务器安装(推荐Docker)依赖文件上传Demo桶操作获取桶的列表获取某个桶中的文件文件操作文件上传(通过本地文件上传)文件上传(通过流进行文件上传)文件下载(获取流)文件删除 前言 文件上传下载是...

    MinIO文件上传

    前言

    文件上传下载是我们平时开发中经常会碰到的场景,这里我们就可以随着博主来简单的搭建一个文件服务,让你可以在10分钟内实现文件的上传下载。


    MinIO服务器安装(推荐Docker)

    1. 安装

    Docker安装时最快最无脑的,一行命令就可以实现。

    • 这里设置了你的账户密码
    • 设置了你的端口号
    • 设置了你的镜像磁盘映射
    docker run -p 9000:9000 --name minio1 \
      -e "MINIO_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE" \
      -e "MINIO_SECRET_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" \
      -v /mnt/data:/data \
      -v /mnt/config:/root/.minio \
      minio/minio server /data
    

    2. 登录你的文件服务

    http://localhost:9000

    账户密码就是你刚刚设置的MINIO_ACCESS_KEY和MINIO_SECRET_KEY。

    依赖

    <dependency>
        <groupId>io.minio</groupId>
        <artifactId>minio</artifactId>
        <version>7.1.2</version>
    </dependency>
    

    文件上传Demo

    
    import io.minio.MinioClient;
    import min_io.Config;
    import io.minio.PutObjectArgs;
    import io.minio.errors.MinioException;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;
    
    public class FileUploader {
    
        private static final String endpoint = "http://localhost:9000";
        private static final String ACCESS_KEY = "AKIAIOSFODNN7EXAMPLE";
        private static final String SECRET_KEY = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY";
        private static final String BUCKET = "asiatrip2";
    
        public static void main(String[] args) throws NoSuchAlgorithmException, IOException, InvalidKeyException {
            try {
                // 使用MinIO服务的URL,端口,Access key和Secret key创建一个MinioClient对象
                MinioClient minioClient = new MinioClient(endpoint,
                        ACCESS_KEY,
                        SECRET_KEY);
    
                // 检查存储桶是否已经存在
                boolean isExist = minioClient.bucketExists(BUCKET);
                if (isExist) {
                    System.out.println("Bucket already exists.");
                } else {
                    // 创建一个名为asiatrip的存储桶,用于存储照片的zip文件。
                    minioClient.makeBucket(BUCKET);
                }
    
                // 使用putObject上传一个文件到存储桶中。
                String fileName = "个人课表.jpg";
                minioClient.putObject(
                        PutObjectArgs.builder().bucket(BUCKET).object(fileName)
                                .stream(new FileInputStream("B:\\"+fileName), -1, 10485760)
                                .contentType("image/png")
                                .build());
                System.out.println(fileName+" is upload success!");
            } catch (MinioException e) {
                System.out.println("Error occurred: " + e);
            }
        }
    }
    

    桶操作

    获取桶的列表

    import io.minio.MinioClient;
    import io.minio.errors.MinioException;
    import io.minio.messages.Bucket;
    import min_io.Config;
    
    import java.io.IOException;
    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;
    import java.util.List;
    
    public class GetBucketList {
    
    
        public static void main(String[] args) throws NoSuchAlgorithmException, IOException, InvalidKeyException {
            try {
                // 使用MinIO服务的URL,端口,Access key和Secret key创建一个MinioClient对象
                MinioClient minioClient = new MinioClient(Config.ENDPOIN,
                        Config.ACCESS_KEY,
                        Config.SECRET_KEY);
    
                // 检查存储桶是否已经存在
                boolean isExist = minioClient.bucketExists(Config.BUCKETS[0]);
                if (isExist) {
                    System.out.println("Bucket already exists.");
                } else {
                    // 创建一个名为asiatrip的存储桶,用于存储照片的zip文件。
                    minioClient.makeBucket(Config.BUCKETS[0]);
                }
    
                // 列出所有存储桶
                List<Bucket> bucketList = minioClient.listBuckets();
                for (Bucket bucket : bucketList) {
                    System.out.println(bucket.creationDate() + ", " + bucket.name());
                }
    
            } catch (MinioException e) {
                System.out.println("Error occurred: " + e);
            }
        }
    }
    

    获取某个桶中的文件

    import io.minio.MinioClient;
    import io.minio.Result;
    import io.minio.errors.MinioException;
    import io.minio.messages.Item;
    import min_io.Config;
    
    import java.io.IOException;
    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;
    
    public class GetBucketFiles {
    
    
        public static void main(String[] args) throws NoSuchAlgorithmException, IOException, InvalidKeyException {
            try {
                // 使用MinIO服务的URL,端口,Access key和Secret key创建一个MinioClient对象
                MinioClient minioClient = new MinioClient(Config.ENDPOIN,
                        Config.ACCESS_KEY,
                        Config.SECRET_KEY);
    
                // 检查存储桶是否已经存在
                boolean isExist = minioClient.bucketExists(Config.BUCKETS[0]);
                if (isExist) {
                    System.out.println("Bucket already exists.");
                } else {
                    // 创建一个名为asiatrip的存储桶,用于存储照片的zip文件。
                    minioClient.makeBucket(Config.BUCKETS[0]);
                }
    
                try {
                    // 检查'mybucket'是否存在。
                    boolean found = minioClient.bucketExists(Config.BUCKETS[0]);
                    if (found) {
                        // 列出'my-bucketname'里的对象
                        Iterable<Result<Item>> myObjects = minioClient.listObjects(Config.BUCKETS[0]);
                        for (Result<Item> result : myObjects) {
                            Item item = result.get();
                            System.out.println(item.lastModified() + ", " + item.size() + ", " + item.objectName());
                        }
                    } else {
                        System.out.println("mybucket does not exist");
                    }
                } catch (MinioException e) {
                    System.out.println("Error occurred: " + e);
                }
    
            } catch (MinioException e) {
                System.out.println("Error occurred: " + e);
            }
        }
    }
    

    文件操作

    文件上传(通过本地文件上传)

    import io.minio.MinioClient;
    import io.minio.PutObjectArgs;
    import io.minio.errors.MinioException;
    import min_io.Config;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;
    
    public class FileUploadLocal {
    
    
        public static void main(String[] args) throws NoSuchAlgorithmException, IOException, InvalidKeyException {
            try {
                // 使用MinIO服务的URL,端口,Access key和Secret key创建一个MinioClient对象
                MinioClient minioClient = new MinioClient(Config.ENDPOIN,
                        Config.ACCESS_KEY,
                        Config.SECRET_KEY);
    
                // 检查存储桶是否已经存在
                boolean isExist = minioClient.bucketExists(Config.BUCKETS[0]);
                if (isExist) {
                    System.out.println("Bucket already exists.");
                } else {
                    // 创建一个名为asiatrip的存储桶,用于存储照片的zip文件。
                    minioClient.makeBucket(Config.BUCKETS[0]);
                }
    
                // 使用putObject上传一个文件到存储桶中。
                String fileName = "pic1.png";
                minioClient.putObject(
                        PutObjectArgs.builder().bucket(Config.BUCKETS[0]).object(fileName)
                                .stream(new FileInputStream("B:\\"+fileName), -1, 10485760)
                                .contentType("image/png")
                                .build());
                System.out.println(fileName+" is upload success!");
            } catch (MinioException e) {
                System.out.println("Error occurred: " + e);
            }
        }
    }
    

    文件上传(通过流进行文件上传)

    import io.minio.MinioClient;
    import io.minio.PutObjectArgs;
    import io.minio.errors.MinioException;
    import min_io.Config;
    
    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;
    
    public class FileUploadStream {
    
    
        public static void main(String[] args) throws NoSuchAlgorithmException, IOException, InvalidKeyException {
            try {
                // 使用MinIO服务的URL,端口,Access key和Secret key创建一个MinioClient对象
                MinioClient minioClient = new MinioClient(Config.ENDPOIN,
                        Config.ACCESS_KEY,
                        Config.SECRET_KEY);
    
                // 检查存储桶是否已经存在
                boolean isExist = minioClient.bucketExists(Config.BUCKETS[0]);
                if (isExist) {
                    System.out.println("Bucket already exists.");
                } else {
                    // 创建一个名为asiatrip的存储桶,用于存储照片的zip文件。
                    minioClient.makeBucket(Config.BUCKETS[0]);
                }
    
                StringBuilder builder = new StringBuilder();
                for (int i = 0; i < 1000; i++) {
                    builder.append("Sphinx of black quartz, judge my vow: Used by Adobe InDesign to display font samples. ");
                    builder.append("(29 letters)\n");
                    builder.append("Jackdaws love my big sphinx of quartz: Similarly, used by Windows XP for some fonts. ");
                    builder.append("(31 letters)\n");
                    builder.append("Pack my box with five dozen liquor jugs: According to Wikipedia, this one is used on ");
                    builder.append("NASAs Space Shuttle. (32 letters)\n");
                    builder.append("The quick onyx goblin jumps over the lazy dwarf: Flavor text from an Unhinged Magic Card. ");
                    builder.append("(39 letters)\n");
                    builder.append("How razorback-jumping frogs can level six piqued gymnasts!: Not going to win any brevity ");
                    builder.append("awards at 49 letters long, but old-time Mac users may recognize it.\n");
                    builder.append("Cozy lummox gives smart squid who asks for job pen: A 41-letter tester sentence for Mac ");
                    builder.append("computers after System 7.\n");
                    builder.append("A few others we like: Amazingly few discotheques provide jukeboxes; Now fax quiz Jack! my ");
                    builder.append("brave ghost pled; Watch Jeopardy!, Alex Trebeks fun TV quiz game.\n");
                    builder.append("- --\n");
                }
                ByteArrayInputStream bais = new
                        ByteArrayInputStream(builder.toString().getBytes("UTF-8"));
                // 创建对象
    //            "mybucket", "myobject", bais, bais.available(), "application/octet-stream")
                minioClient.putObject(
                        PutObjectArgs.builder()
                                .bucket(Config.BUCKETS[0])
                                .object(Config.TEXT_FILE)
                                .contentType("text/text")
                                .stream(bais, bais.available(), -1)
                                .build()
                );
    
                bais.close();
                System.out.println("myobject is uploaded successfully");
    
            } catch (MinioException e) {
                System.out.println("Error occurred: " + e);
            }
        }
    }
    

    文件下载(获取流)

    import io.minio.MinioClient;
    import io.minio.errors.MinioException;
    import min_io.Config;
    
    import java.io.IOException;
    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;
    
    public class GetDownloadFile {
        /**
         * MinioClient.getObject() example.
         */
        public static void main(String[] args)
                throws IOException, NoSuchAlgorithmException, InvalidKeyException {
            try {
                /* play.min.io for test and development. */
                MinioClient minioClient =
                        MinioClient.builder()
                                .endpoint(Config.ENDPOIN)
                                .credentials(Config.ACCESS_KEY, Config.SECRET_KEY)
                                .build();
    
                // 调用statObject()来判断对象是否存在。
                // 如果不存在, statObject()抛出异常,
                // 否则则代表对象存在。
                minioClient.statObject(Config.BUCKETS[0], Config.FILES[1]);
    
                // 获取myobject的流并保存到photo.jpg文件中。
                minioClient.getObject(Config.BUCKETS[0], Config.FILES[1], "B:\\photo.jpg");
    
            } catch (MinioException e) {
                System.out.println("Error occurred: " + e);
            }
        }
    }
    

    文件删除

    import io.minio.MinioClient;
    import io.minio.RemoveObjectsArgs;
    import io.minio.Result;
    import io.minio.errors.MinioException;
    import io.minio.messages.DeleteError;
    import io.minio.messages.DeleteObject;
    import min_io.Config;
    
    import java.io.IOException;
    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;
    import java.util.LinkedList;
    import java.util.List;
    
    public class DeleteFile {
      /** MinioClient.removeObject() example removing multiple objects. */
      public static void main(String[] args)
          throws IOException, NoSuchAlgorithmException, InvalidKeyException {
        try {
          /* play.min.io for test and development. */
          MinioClient minioClient =
              MinioClient.builder()
                  .endpoint(Config.ENDPOIN)
                  .credentials(Config.ACCESS_KEY, Config.SECRET_KEY)
                  .build();
    
    
          List<DeleteObject> objects = new LinkedList<>();
          objects.add(new DeleteObject(Config.FILES[0]));
          objects.add(new DeleteObject(Config.FILES[1]));
          Iterable<Result<DeleteError>> results =
              minioClient.removeObjects(
                  RemoveObjectsArgs.builder().bucket(Config.BUCKETS[0]).objects(objects).build());
          for (Result<DeleteError> result : results) {
            DeleteError error = result.get();
            System.out.println(
                "Error in deleting object " + error.objectName() + "; " + error.message());
          }
        } catch (MinioException e) {
          System.out.println("Error occurred: " + e);
        }
      }
    }
    
    展开全文
  • 使用QT实现文件上传和下载----ftp服务器

    千次下载 热门讨论 2014-07-16 17:07:49
    使用QT实现文件上传和下载,服务器为FTP服务器,这是一个简单的测试源码。希望能够给初学者一定的启发。
  • ASP.NET Web API 接收文件上传

    热门讨论 2015-05-24 10:07:42
    ASP.NET Web API File Upload and Multipart MIME
  • java操作mongoDB实现文件上传预览打包下载

    千次下载 热门讨论 2013-09-16 16:20:52
    主要功能:文件上传、下载、预览、打包下载
  • 在Web API中使用jQuery AJAX实现文件上传的例子

    千次下载 热门讨论 2014-09-09 02:21:15
    在Web API中使用jQuery AJAX实现文件上传的例子
  • SpringBoot + Vue 实现文件上传功能,文件下载功能
  • SpringCloud文件上传

    千次阅读 2019-09-05 16:45:06
    文件上传并不只是在品牌管理中有需求,以后的其它服务也可能需要,因此我们创建一个独立的微服务,专门处理各种上传。 2.1.搭建项目 2.1.1.创建SpringCloud项目 2.1.2.添加依赖 我们需要EurekaClient和web依赖: &...
  • base64文件上传 和 传统流文件上传

    千次阅读 2019-09-02 22:42:11
    1.base64文件上传,传的数据会比传统的文件上传大 2.base64 就是传一个超大的字符串,可能会吃掉很大的内存 3.减少http请求 3.base64上传 1. 设置http请求的大小 server: tomcat: max-...
  • 使用LayUI进行文件上传(多文件上传)

    千次阅读 2019-08-15 16:31:42
    使用LayUI进行文件上传(多文件上传) 1、添加LayUI上传组件需要的js文件 jquery.min.js、layui.all.js、layer.js 2、导入Java上传组件包 commons-fileupload、commons-io 3、在spring中配置上传文件大小限制 <!-...
  • Web安全-文件上传漏洞与WAF绕过

    万次阅读 多人点赞 2018-12-29 10:15:51
    这种攻击方式是最为直接和有效的,“文件上传”本身没有问题,有问题的是文件上传后,服务器怎么处理、解释文件。如果服务器的处理逻辑做的不够安全,则会导致严重的后果。 1、文件上传后导致的常见安全问题一般有:...
  • SpringBoot 文件上传(可配置文件上传路径) 1. 在application.yml中配置文件上传路径 ,上传文件大小 application: #版本 version: 1.0.0 #文件上传路径 profile: D:/profile/ spring: servlet: multipart: ...
  • SpringMVC+ajax文件上传实例教程

    万次阅读 多人点赞 2018-07-26 15:34:04
    文件上传 文件上传是项目开发中最常见的功能。为了能上传文件,必须将表单的method设置为POST,并将enctype设置为multipart/form-data。只有在这样的情况下,浏览器才会把用户选择的文件以二进制数据发送给服务器。...
  • 揭秘前端文件上传原理(一)

    万次阅读 多人点赞 2019-09-06 08:00:00
    在平时工作中,总是会接触过很多文件上传的功能,因为用惯了各种操作库来处理,所以总有一种云里雾里的感觉,没有清晰的思路,归根到底还是没有理解文件上传的原理。接下来将揭起工具...
  • PHP实现文件上传

    万次阅读 多人点赞 2019-04-10 23:54:33
    很多网站都需要实现文件上传功能,这个功能说大不大,说小不小,但是如果文件上传出现漏洞,可能会导致网站的控制权被hack拿下,所有文件上传的控制要做到严格严格再严格,为了更加深刻研究文件上传漏洞的原理,本文...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,325,926
精华内容 530,370
关键字:

文件上传