精华内容
下载资源
问答
  • SpringBoot文件上传下载和多文件上传(图文详解)

    万次阅读 多人点赞 2017-01-16 20:16:02
    最近在学习SpringBoot,以下是最近学习整理的实现文件上传下载的java代码: 1、开发环境: IDEA15+ Maven+JDK1.8 2、新建一个maven工程: 3、工程框架 4、pom.xml文件依赖项...

    本人微信公众号:CPP进阶之旅
    如果觉得这篇文章对您有帮助,欢迎关注 “CPP进阶之旅” 学习更多技术干货

    最近在学习SpringBoot,以下是最近学习整理的实现文件上传下载的java代码:
    1、开发环境:
    IDEA15+ Maven+JDK1.8
    2、新建一个maven工程:
    这里写图片描述
    3、工程框架
    这里写图片描述
    4、pom.xml文件依赖项

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>SpringWebContent</groupId>
      <artifactId>SpringWebContent</artifactId>
      <packaging>war</packaging>
      <version>1.0-SNAPSHOT</version>
      <name>SpringWebContent Maven Webapp</name>
      <url>http://maven.apache.org</url>
      <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.3.RELEASE</version>
      </parent>
      <dependencies>
        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-devtools</artifactId>
          <optional>true</optional>
        </dependency>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>3.8.1</version>
          <scope>test</scope>
        </dependency>
      </dependencies>
      <properties>
        <java.version>1.8</java.version>
      </properties>
      <build>
        <finalName>SpringWebContent</finalName>
      <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
      </build>
    </project>
    

    5、Application.java

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    @SpringBootApplication
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    }
    

    6、FileController.java

    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.multipart.MultipartFile;
    import org.springframework.web.multipart.MultipartHttpServletRequest;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.*;
    import java.util.List;
    
    @Controller
    public class FileController {
        @RequestMapping("/greeting")
        public String greeting(@RequestParam(value="name", required=false, defaultValue="World") String name, Model model) {
            model.addAttribute("name", name);
            return "greeting";
        }
        private static final Logger logger = LoggerFactory.getLogger(FileController.class);
        //文件上传相关代码
        @RequestMapping(value = "upload")
        @ResponseBody
        public String upload(@RequestParam("test") MultipartFile file) {
            if (file.isEmpty()) {
                return "文件为空";
            }
            // 获取文件名
            String fileName = file.getOriginalFilename();
            logger.info("上传的文件名为:" + fileName);
            // 获取文件的后缀名
            String suffixName = fileName.substring(fileName.lastIndexOf("."));
            logger.info("上传的后缀名为:" + suffixName);
            // 文件上传后的路径
            String filePath = "E://test//";
            // 解决中文问题,liunx下中文路径,图片显示问题
            // fileName = UUID.randomUUID() + suffixName;
            File dest = new File(filePath + fileName);
            // 检测是否存在目录
            if (!dest.getParentFile().exists()) {
                dest.getParentFile().mkdirs();
            }
            try {
                file.transferTo(dest);
                return "上传成功";
            } catch (IllegalStateException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return "上传失败";
        }
    
        //文件下载相关代码
        @RequestMapping("/download")
        public String downloadFile(org.apache.catalina.servlet4preview.http.HttpServletRequest request, HttpServletResponse response){
            String fileName = "FileUploadTests.java";
            if (fileName != null) {
                //当前是从该工程的WEB-INF//File//下获取文件(该目录可以在下面一行代码配置)然后下载到C:\\users\\downloads即本机的默认下载的目录
                String realPath = request.getServletContext().getRealPath(
                        "//WEB-INF//");
                File file = new File(realPath, fileName);
                if (file.exists()) {
                    response.setContentType("application/force-download");// 设置强制下载不打开
                    response.addHeader("Content-Disposition",
                            "attachment;fileName=" +  fileName);// 设置文件名
                    byte[] buffer = new byte[1024];
                    FileInputStream fis = null;
                    BufferedInputStream bis = null;
                    try {
                        fis = new FileInputStream(file);
                        bis = new BufferedInputStream(fis);
                        OutputStream os = response.getOutputStream();
                        int i = bis.read(buffer);
                        while (i != -1) {
                            os.write(buffer, 0, i);
                            i = bis.read(buffer);
                        }
                        System.out.println("success");
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        if (bis != null) {
                            try {
                                bis.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                        if (fis != null) {
                            try {
                                fis.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
            return null;
        }
        //多文件上传
        @RequestMapping(value = "/batch/upload", method = RequestMethod.POST)
        @ResponseBody
        public String handleFileUpload(HttpServletRequest request) {
            List<MultipartFile> files = ((MultipartHttpServletRequest) request)
                    .getFiles("file");
            MultipartFile file = null;
            BufferedOutputStream stream = null;
            for (int i = 0; i < files.size(); ++i) {
                file = files.get(i);
                if (!file.isEmpty()) {
                    try {
                        byte[] bytes = file.getBytes();
                        stream = new BufferedOutputStream(new FileOutputStream(
                                new File(file.getOriginalFilename())));
                        stream.write(bytes);
                        stream.close();
    
                    } catch (Exception e) {
                        stream = null;
                        return "You failed to upload " + i + " => "
                                + e.getMessage();
                    }
                } else {
                    return "You failed to upload " + i
                            + " because the file was empty.";
                }
            }
            return "upload successful";
        }
    

    7、index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <title>Getting Started: Serving Web Content</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    </head>
    <body>
    <p>Get your greeting <a href="/greeting">here</a></p>
    <form action="/upload" method="POST" enctype="multipart/form-data">
        文件:<input type="file" name="test"/>
        <input type="submit" />
    </form>
    <a href="/download">下载test</a>
    <p>多文件上传</p>
    <form method="POST" enctype="multipart/form-data" action="/batch/upload">
        <p>文件1:<input type="file" name="file" /></p>
        <p>文件2:<input type="file" name="file" /></p>
        <p><input type="submit" value="上传" /></p>
    </form>
    </html>
    
    

    本文代码参考Spring官网:https://spring.io/guides/gs/serving-web-content/
    完整工程地址:http://download.csdn.net/detail/coding13/9739116

    欢迎关注我的个人微信公众号,查看专业的客户端/服务端开发知识、笔试面试题目、程序员职场经验与心得分享。
    在这里插入图片描述

    展开全文
  • Django实战之文件上传下载

    千次阅读 多人点赞 2019-09-07 10:47:04
    最近学习django,通过文件上传下载这个小项目,总结下常用的知识点。 做这个案例我有以下需求: 1.要支持一次上传多个文件 2.支持上传后记录上传的数据以及列表展示 3.支持下载和删除文件记录 效果展示 ...

    项目介绍

    最近学习django,通过文件上传下载这个小项目,总结下常用的知识点。
    做这个案例我有以下需求:

    1.要支持一次上传多个文件

    2.支持上传后记录上传的数据以及列表展示

    3.支持下载和删除文件记录

     

    效果展示

     

    数据库记录

     

    开发步骤

     

    创建项目:

    django-admin startproject file_upload
    cd file_upload
    python manage.py startapp uploader

    目录结构:

     

    0.settings.py

    LANGUAGE_CODE = 'zh-Hans'
    
    TIME_ZONE = 'Asia/Shanghai'
    
    USE_I18N = True
    
    USE_L10N = True
    
    USE_TZ = False

    1.urls.py

    父:

    from django.contrib import admin
    from django.urls import path, include
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('uploader/', include('uploader.urls'))
    ]

    子:

    from django.contrib import admin
    from django.urls import path, include
    from . import views
    
    app_name = 'uploader'
    
    urlpatterns = [
        path('', views.upload, name='upload'),  # 上传
        path('list/', views.list),  # 列表
        path('download/<id>', views.download, name='download'),  # 下载
        path('delete/<id>', views.delete, name='delete'),  # 删除
    ]

    2.models.py

    from django.db import models
    from django.utils import timezone
    
    '''
    文件记录
    '''
    class FileInfo(models.Model):
        file_name = models.CharField(max_length=500)
        file_size = models.DecimalField(max_digits=10, decimal_places=0)
        file_path = models.CharField(max_length=500)
        upload_time = models.DateTimeField(default=timezone.now())
    

    3.forms.py

    from django import forms
    
    '''
    上传表单
    '''
    class UploadForm(forms.Form):
        file = forms.FileField(
            widget=forms.ClearableFileInput(attrs={'multiple': True}),  # 支持多文件上传
            label='选择文件...',
            help_text='最大100M'
        )
    

    4.views.py

    from django.shortcuts import render
    from django.http import HttpResponseRedirect
    from django.http import HttpResponseRedirect
    from django.http import FileResponse
    from django.template import RequestContext
    from django.urls import reverse
    from django.utils.http import urlquote
    
    from .models import FileInfo
    from .forms import UploadForm
    import os
    
    
    # 上传文件
    def upload(request):
        # Handle file upload
        if request.method == 'POST':
            form = UploadForm(request.POST, request.FILES)
            if form.is_valid():
                files = request.FILES.getlist('file')
                for f in files:
                    file_info = FileInfo(file_name=f.name, file_size=1 if 0 < f.size < 1024 else f.size / 1024, file_path=os.path.join('D:\\upload', f.name))
                    file_info.save()
                    # 上传
                    destination = open(os.path.join("D:\\upload", f.name), 'wb+')
                    for chunk in f.chunks():
                        destination.write(chunk)
                    destination.close()
    
                # 返回上传页
                return HttpResponseRedirect('/uploader/list')
        else:
            form = UploadForm()  # A empty, unbound form
        return render(request, 'uploader/upload.html', {'form': form})
    
    
    # 文件列表
    def list(request):
        file_infos = FileInfo.objects.all()
    
        return render(request, 'uploader/list.html', {'file_infos': file_infos})
    
    
    # 下载文件
    def download(request, id):
        file_info = FileInfo.objects.get(id=id)
        print('下载的文件名:' + file_info.file_name)
        file = open(file_info.file_path, 'rb')
        response = FileResponse(file)
        response['Content-Disposition'] = 'attachment;filename="%s"' % urlquote(file_info.file_name)
        return response
    
    
    # 删除文件
    def delete(request, id):
        file_info = FileInfo.objects.get(id=id)
        file_info.delete()
        file_infos = FileInfo.objects.all()
    
        return HttpResponseRedirect('/uploader/list')

     

    需要源码的朋友留下邮箱。

     

     

     

     

     

    展开全文
  • 解决中文文件上传下载中文乱码和文件上传失败下载文件为0kb /** * @author xh 测试成功 可以上传中文文件 * @param url * @param port * @param username * @param password * @param remotePath * @param fileName...

     解决中文文件上传下载中文乱码和文件上传失败下载文件为0kb

    /**

    * @author xh 测试成功 可以下载中文文件  ftp默认的编码为gbk
    * @param url
    * @param port
    * @param username
    * @param password
    * @param remotePath
    * @param fileName
    * @param localPath
    * @return
    */
    public static boolean downFtpFile(String url, int port, String username,  
                String password, String remotePath, String fileName,  
                String localPath) {  
            boolean success = false;  
            FTPClient ftp = new FTPClient();  
            try {  
                int reply;  
                ftp.connect(url, port);  
                // 如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器  
                ftp.login(username, password);// 登录  
                reply = ftp.getReplyCode();  
                if (!FTPReply.isPositiveCompletion(reply)) {  
                    ftp.disconnect();  
                    return success;  
                }  
                ftp.changeWorkingDirectory(remotePath);// 转移到FTP服务器目录  
                FTPFile[] fs = ftp.listFiles();  
                for (FTPFile ff : fs) {  
                    String fname = new String(ff.getName().getBytes("iso-8859-1"),  
                            "gbk");  
                    if (fname.equals(fileName)) {  
                        File localFile = new File(localPath+fname);  
                        OutputStream is = new FileOutputStream(localFile);  
                        ftp.retrieveFile(ff.getName(), is);  
                        is.close();  
                        break;  
                    }  
                }  
                ftp.logout();  
                success = true;  
            } catch (IOException e) {  
                e.printStackTrace();  
            } finally {  
                if (ftp.isConnected()) {  
                    try {  
                        ftp.disconnect();  
                    } catch (IOException ioe) {  
                    }  
                }  
            }  
            return success;  
        }  


    /**
     * @author xh 测试成功 可以上传中文文件
     * @param url
     * @param port
     * @param username
     * @param password
     * @param path
     * @param filename
     * @param input
     * @return
     */
    public static boolean uploadFile(String url,int port,String username, String password, String path, String filename, InputStream input) {
    boolean success = false;
    FTPClient ftp = new FTPClient();
      try {
       int reply;
       ftp.connect(url, port);//连接FTP服务器
    //如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器
    ftp.login(username, password);//登录
    reply = ftp.getReplyCode();

    if (!FTPReply.isPositiveCompletion(reply)) {
    ftp.disconnect();
    return success;
                  }
    ftp.changeWorkingDirectory(path);
    ftp.setControlEncoding("ISO-8859-1");
    ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
      ftp.storeFile(new String(filename.getBytes("GBK"),"ISO-8859-1"), input); 
    input.close();
    ftp.logout();
    success = true;


        } catch (IOException e) {
    e.printStackTrace();
    } finally {
    if (ftp.isConnected()) {
    try {
    ftp.disconnect();
    } catch (IOException ioe) {}
    }

    }
      return success;
    }

    展开全文
  • SpringMVC文件上传下载实战(单文件、多文件)

    千次阅读 多人点赞 2020-07-30 20:03:27
    大家好,我是bigsai,今天我们学习Springmvc的文件上传下载。文件上传和下载是互联网web应用非常重要的组成部分,它是信息交互传输的重要渠道之一。本文为你揭开SpringMVC文件上传下载的面纱!

    前言

    大家好,我是bigsai,今天我们学习Springmvc的文件上传下载。

    文件上传和下载是互联网web应用非常重要的组成部分,它是信息交互传输的重要渠道之一。你可能经常在网页上传下载文件,你可能也曾沉浸于互联网技术的神秘,而本篇就为你解开它神秘的面纱。

    本文已收录在公众号:bigsai中(微信搜索bigsai),,同时也收录在博学谷中(以关卡方式展开欢迎体验),更多好玩精彩等待给您分享,欢迎关注!

    案例分析

    你肯定会问:通过本篇可能能够学到什么?

    那我很负责任的告诉你,通过本篇文章,你能够掌握Springmvc文件上传(单文件、多文件)文件下载知识和内容的使用,并能够根据这些实现一些基本的案例。

    核心思路拆解

    你可能会问:,这么一个完整的项目是如何分工运行?

    不急不急,我来告诉你,其实这么一个文件上传下载的项目,它是一个b-s结构的web项目,涉及到前端和服务端,从宏观来看它是这样的一个结构:

    在这里插入图片描述

    但是从文件上传、下载两个功能来看它们之间又是有所区别的,文件上传的主要核心是用户上传的文件服务端接受存储

    在这里插入图片描述

    而文件下载更重要的部分是用户请求之后服务端给用户返回二进制文件

    在这里插入图片描述

    所以文件上传和文件下载的项目大体结构相似,只是各个部分在具体实现上有差别,我们需要更多关注下文件上传和下载服务端的实现和区别。

    案例所涉及知识点

    在本案例中,用到了以下知识点:

    html页面form表单:

    在前端无论是html还是jsp等模板引擎编写上传的页面时候。<form> 标签就意为一个(文件)上传的表单。

    • 表单能够包含若干 input 标签,而input标签又有不同类型比如文本字段、复选框、单选框、文件等等。
    • 我们通常使用表单编写若干标签代表我们想要向服务端发送的数据,然后通过标签的按钮将数据请求提交至服务端。
    • 表单的method表示请求的类型(一般为post),action表示需要请求的url地址,enctype表示传输数据类型。

    Springmvc:

    案例的文件上传和下载基于Springmvc,而我们在Springboot项目中整合Springmvc。

    • 本案例使用Springmvc作为项目mvc架构的框架,将模型(Model),视图(View),控制器(Controller)分离降低项目的耦合性。
    • 本案例使用Springmvc的MultipartFile接口和ResponseEntity接口实现文件上传和下载。

    创建Springmvc项目

    Springmvc为一个mvc架构的web框架,创建Springmvc项目的方式有很多,你可以选择直接通过IDEA创建Springmvc项目,也可以通过Maven方式创建web项目然后添加Springmvc的依赖,但这两种方式有太多的配置还需要配置tomcat,在效果一致的情况下咱们尽量简化一些开发配置类的工作,所以不采用以上两种方式创建项目。

    而Springboot简化了Spring项目的开发,开箱即用,且内嵌tomcat,所以咱们选择创建基于Springboot且整合Springmvc的项目方便快捷,更能直奔主题进行操作。

    项目创建

    首先,打开IDEA,创建项目,选择Spring Initializr类型初始化点击next。
    在这里插入图片描述
    然后你会得到一个选择项目名和一些配置的页面,我们在Group中填写com,而Artifact咱们填写fileupload。点击next。
    在这里插入图片描述
    接着在选择对应模块依赖的时候,选择Spring web 模块,此模块就是包含Springmvc的web模块
    在这里插入图片描述
    接着选择需要创建项目的地址目录,点击next在这里插入图片描述

    这样你就可以得到一个完整的包含web模块(Springmvc)的Springboot项目,就可以在里面编写咱们项目的代码。
    在这里插入图片描述

    目录介绍

    上面创建完的基于Springboot的Springmvc项目,默认有若干文件和文件夹,不同文件和文件夹有着不同的职责:

    • java:用来编写java服务端相关代码,例如Controller,Dao,Service等。
    • application.properties: 编写一些项目和框架的配置内容以及和第三方框架整合配置等
    • static: 静态资源目录,用来存放html、JavaScript、图片等资源。
    • teamplates:用来编写Thymeleaf等模板引擎,这里不使用
    • pom.xml:编写maven项目jar包资源依赖。如果项目需要引入其他依赖或者修改打包方式可以进行修改。

    对于web项目的文件上传,需要进行一定配置以满足我们的使用需求,我们在application.propertis进行以下配置:

    # 允许项目中文件上传
    spring.servlet.multipart.enabled=true
    # 上传文件的临时目录 (一般情况下不用特意修改)
    #spring.servlet.multipart.location=
    # 上传文件最大为 1M (默认值 1M 根据自身业务自行控制即可)
    spring.servlet.multipart.max-file-size=104857600
    # 上传请求最大为 10M(默认值10M 根据自身业务自行控制即可)
    spring.servlet.multipart.max-request-size=104857600
    # 文件大小阈值,当大于这个阈值时将写入到磁盘,否则存在内存中,(默认值0 一般情况下不用特意修改)
    spring.servlet.multipart.file-size-threshold=0
    # 判断是否要延迟解析文件(相当于懒加载,一般情况下不用特意修改)
    spring.servlet.multipart.resolve-lazily=false
    

    当然,你对文件有大小等其他要求可以对配置进行自行更改。到这里带有Springmvc环境的项目已经创建完成啦,剩下的只需要编写前端、服务端代码运行测试即可。

    单文件上传

    下面请跟我实战 Springmvc单文件上传。一个完整的文件上传项目有两部分组成:前端界面和服务端程序。

    前端设计

    对于前端页面,我们使用你一定熟悉的html而不选用其他模板引擎。而form表单是html文件上传的核心组件,你在使用前需要了解它的一些属性。

    表单的enctype属性
    上面说了一个表单文件传输的大体流程,你也知道表单有个至关重要的属性:enctype。而entype值通常有以下三种:

    • application/x-www-form-urlencoded:默认编码方式,在发送前编码所有字符(默认)使用url编码方式,和get请求有些相似。但这种方式如果发送大量二进制数据效率会比较低。
    • multipart/form-data:不对字符编码。在使用包含文件上传控件的表单时,必须使用该值。通常用来向服务端发送二进制数据,而我们的文件也主要以二进制的方式进行传输。
    • text/plain:空格转换为 “+” 加号,但不对特殊字符编码。

    所以本单文件上传案例中,需要注意以下事项:

    • 表单的enctype要为multipart/form-data类型,表示二进制传输。
    • 在一个form表单内定义一个input为file属性的标签,代表文件上传。
    • form表单的method需要为post。
    • enctype要为multipart/form-data类型,表示二进制传输。

    前端页面的规则了解之后你在static下创建一个index1.html文件,里面具体的代码内容为:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>单文件上传</title>
    </head>
    <body>
    <h2>单文件上传</h2>
    <form  action="onfile" method="post" enctype='multipart/form-data'>
        <input type="file" name="file" ><br>
        <input type="submit" value="提交">
    </form>
    </body>
    </html>
    

    其中action="onfile"代表的为请求地址为onfile,这里都在项目内所以用相对地址即可,如果上传为其他接口也可填写对应的绝对地址。这样前端页面就编写完成,我们还需要编写文件上传对应服务端模块。

    服务端设计

    服务端主要负责文件接受,在前端看起来实现文件上传的页面很简单,但实际上在服务端的文件接收并没有那么容易,因为传过来的不光光是这一个(或多个)二进制文件,还附带一些头信息、文件名等等数据。打包过来的数据如果是文本数据解析可能还好,但是二进制文件数据一旦出现一点错误可能得到的整个文件都是损坏的。并且在咱们java web技术栈中文件上传也是有一定发展的历史的:

    servlet文件上传(3.0以前)
    在servlet3.0以前,文件上传在服务端接收需要使用request.getInputStream()获取表单的二进制数据,但是在解析时候非常麻烦和复杂,对于文件上传这么一个很基本的模块在接收的时候可能要耗费很大的成本和精力去解决它,并且很多初级攻城狮很可能由于对io模块陌生无法实现上传文件在服务端的接收。
    在这里插入图片描述

    所以这个时候一些具有责任感的公司、组织就把它们的解析方法贡献出来供大家使用,大家不需了解传输文件底层内容,这些开源的处理方式中,最流行的当属apache旗下开源的commons-fileuploadcommons-io,把两个jar包加入到项目中你直接了解下这个api如何使用即可。有了这两个jar包,简单学习它的api,你就可以在普通的web项目中很容易的实现上传文件的功能!
    在这里插入图片描述
    servlet3.0以后
    随着servlet版本更新,设计者可能看到javaweb开发中原生api对文件上传支持不太友好的问题,所以在api对文件上传的支持得到优化,简化了Java Web的开发。在servlet3.0中主要增加Part这个类用来读取文件数据和信息,在Part中直接将传输文件的名称、头信息、二进制文件分割开,通过简单的api就可以实现文件上传的功能。不需要再添加外部jar包

    Springmvc文件上传
    文件上传和下载是web开发常用模块,而Springmvc作为一款优秀的web框架,对很多模块和内容进行更高度的封装和集成,而这么常用的文件上传肯定是少不了的,所以Springmvc的文件上传基于apache旗下开源的commons-fileuploadcommons-io包。将其进行二次集成和封装至Springmvc,将方法和内容封装至MultipartFile接口让我们使用起来更加方便,能够容易实现单文件、多文件上传。

    对于上述各种文件上传服务端实现方式,大致可以通过下图展示:
    在这里插入图片描述
    通过上图你就可明白Springmvc文件上传实现的原理,那么下面你就可以进行大显身手啦!Springmvc处理上传文件很简单,我们需要在java目录下创建一个uploadController.java创建这么一个控制器,在上面加上@Controller注解。在Controller中编写以下代码:

     @PostMapping("onfile")
     @ResponseBody
     public String onfile(MultipartFile file) throws IOException {
         File file1 =new File("F:/fileupload/"+file.getOriginalFilename());//创建file对象
         if(!file1.exists())
                file1.createNewFile();//在磁盘创建该文件
         file.transferTo(file1);//将接受的文件存储
         return "sucucess";
     }
    

    其中:

    • @PostMapping(“onfile”) 的意思为该请求方式为post,且请求的url在项目中的相对地址为onfile
    • @ResponseBody指不返回web页面,而是返回字符串或json字符串,在这里我们直接用一个成功单词代表跳转后的界面。
    • public String onfile(MultipartFile file) 函数名不重复就行,而MultipartFile file就是Springmvc封装的一个处理文件的接口,其中参数名(这里是file)要和前端界面文件名相同(input type=“file”,name="file"中的name),通过这个接口你可以更容易的对文件进行各种操作,而本案例就是将上传的文件保存到本地F盘。

    对于函数中的几行核心代码各司其职,除了注释的解释外,大致的流程可以参考如下图:
    在这里插入图片描述

    运行测试

    这样启动项目,在浏览器输入http://localhost:8080/index1.html,选择文件上传,点击上传之后就可以在本地看到上传的文件啦。
    在这里插入图片描述
    至此,单文件上传就完成啦,单文件上传前端需要注意的就是form表单的method类型以及 enctype参数,而服务端也只需要用MultipartFile 接口就可以很容易的对文件进行接受。

    多文件上传

    上面讲的是单文件上传,很多时候你可能遇到的需求不光光是单文件上传。就比如你一定熟悉这个页面:
    在这里插入图片描述

    如上你可以看到,这么一次文件上传不止一个图片,并且数量也不确定,但都属于同一名称和集合的内容。这就是多文件上传。对于这种情况无论在前端还是服务端也是很容易处理的。

    前端设计

    我们这里实现一个多张图片的上传,首先在static目录下创建一个index2.html的页面。里面的具体内容为:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>多文件上传</title>
    </head>
    <body>
    <h2>同一类别多个文件上传</h2>
    <form name="onfile"  action="onfiles2" method="post" enctype="multipart/form-data">
        图片:
        <input type="file" name="img"><br>
        <input type="file" name="img"><br>
        <input type="file" name="img"><br>
        <input type="file" name="img"><br>
        <input type="submit" value="提交">
    </form>
    </body>
    </html>
    

    这样前端页面就编写完成,其中action要改为onfiles2,也就是待会要在服务端编写的接口。还有注意的这些input 所有type为file代指类型为文件,而name均为img意思是上传一组名称为img图片的集合。

    服务端设计

    而在我们服务端,其实用MultipartFile[]数组就可以对这样的多文件进行接收,我们在controller中编写以下代码:

    @PostMapping("onfiles2")
    @ResponseBody
    public String onfiles2(MultipartFile img[]) throws IOException {
       for(int i=0;i<img.length;i++)
       {
           if(!img[i].isEmpty())//文件不空
           {
               File imgfile =new File("F:/fileupload/"+img[i].getOriginalFilename());
               imgfile.createNewFile();
               img[i].transferTo(imgfile);
               logger.info(img[i].getOriginalFilename());
           }
       }
        return "sucucess";
    }
    

    这个处理方式和前面的很相似,只不过是需要遍历MultipartFile[]对每个文件进行接收处理,当然文件为空的时候不进行处理。

    运行测试

    这样打开浏览器输入:http://localhost:8080/index2.html,上传文件测试效果:
    在这里插入图片描述

    这样一组类似相册上传的功能就完成啦,当然实际开发中的文件上传的要求肯定比这个要求严格很多,可能对文件的格式、大小都有一定的要求,这就要求你在前端和服务端都要对文件的后缀名、大小等信息进行校验,以达到自己场景化的需求。

    文件下载

    文件下载估计你在日常生活中会经常遇到,而你下载的其实就是服务端(服务器)的资源,对于文件类型有多种多样的,浏览器也能够识别很多种资源,事实上你现在访问的这个网页也是服务端的html文件、图片文件等资源,只不过这些资源浏览器能够显示而不会保存到本地。

    直接访问资源VS下载资源

    如果直接访问的资源是浏览器所不能识别解析的,例如doc、zip等类型文件,那访问的时候会默认下载到本地。而当你在Springmvc中使用下载功能时,无论是什么资源都以下载的形式返回给客户端。这种区别可以参考下图:
    在这里插入图片描述

    在文件下载方面的实现,servlet本身也是实现文件下载的,不过使用起来有点繁琐。其原理就是往HttpServletResponse response的输出流写字节内容。而我们Springmvc对文件下载也做了封装,将下载功能封装至ResponseEntity类中,我们在使用的时候也很方便。下面就来实战文件下载的功能。

    首先,我们在F盘建立download文件夹,在里面添加对应文件,这个文件夹我们作为服务端的资源。
    在这里插入图片描述

    前端设计

    我们在创建一个文件下载的前端页面,在static目录下创建index3.html,页面的具体内容为:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Springmvc文件下载</title>
    </head>
    <body>
    <h2>Springmvc文件下载</h2>
    个人照片<a href="/download/个人照片.png">个人照片.png</a><br>
    个人简历<a href="/download/个人简历.pdf">个人简历.pdf</a>
    </body>
    </html>
    

    其中href是下载的超链接,download是下载的接口名,而链接最后面部分则是下载资源名称。

    服务端设计

    文件下载的原理就是服务端向客户端返回二进制流和信息,而Springmvc通过ResponseEntity完成。我们在controller中编写以下接口实现下载的功能:

    @GetMapping("download/{filename}")
    public ResponseEntity<byte[]>download(@PathVariable String filename) throws IOException {
        //下载文件的路径(这里绝对路径)
        String filepath= "F:/download/"+filename;
        File file =new File(filepath);
        //创建字节输入流,这里不实用Buffer类
        InputStream in = new FileInputStream(file);
        //available:获取输入流所读取的文件的最大字节数
        byte[] body = new byte[in.available()];
        //把字节读取到数组中
        in.read(body);
        //设置请求头
        MultiValueMap<String, String> headers = new HttpHeaders();
        headers.add("Content-Disposition", "attchement;filename=" + file.getName());
        //设置响应状态
        HttpStatus statusCode = HttpStatus.OK;
        in.close();
        ResponseEntity<byte[]> entity = new ResponseEntity<byte[]>(body, headers, statusCode);
        return entity;//返回
    }
    

    这样就是实现了文件下载功能,如果用传统servlet的方式下载文件可能需要在HttpServletResponse response中设置各种信息,而使用Springmvc的ResponseEntity只需要将文件二进制主体、头信息以及状态码设置好即可进行文件下载,在易用性和简洁上更胜一筹。

    运行测试

    打开浏览器输入:http://localhost:8080/index3.html;点击需要下载的文件,就实现了文件下载的功能,运行情况图如下:
    在这里插入图片描述

    此时你就遇到了一个文件下载非常常见的问题:中文文件名错误显示。这个解决方案也很容易解决,只需将Content-Disposition内容后面的文件名进行url编码即可,具体代码为(替换上面对于部分):

    headers.add("Content-Disposition", "attchement;filename=" + URLEncoder.encode(file.getName(), "UTF-8"));
    

    这样重启程序,刷新页面再次点击下载的链接,你就会发现文件被成功的下载了:
    在这里插入图片描述

    总结与拓展

    至此,Springmvc的单文件上传、多文件上传以及文件下载你已经全部掌握了,是不是满满的成就感想去实现一个自己的小网站并把相关内容放进去?不过Springmvc文件上传下载虽然简单,但你依然需要掌握其原理,学好java中的io文件传输,这样在各种场景的文件传输任务中方能胜任。

    总结

    前面所讲文件上传,前端就是form表单用<input type="file">表示客户端要上传文件,而服务端主要使用MultipartFile或者MultipartFile[]分别接收单个文件和多个文件。而在存储到本地也仅仅需要在本地磁盘创建对应文件然后MultipartFile调用transferTo()方法即可将上传的文件储存。

    而文件下载的前端需要一个请求的url链接,服务端需要编写这个链接对应的接口。通过一些名称找到文件在本地真实的位置通过ResponseEntity即可将二进制文件返回给客户达到文件下载的功能。而ResponseEntity使用也很简单在创建时候只需要传入二进制主体、头和状态码即可成功返回,而这些Springmvc已进行了很好封装你可以直接使用。

    而无论是文件上传、多文件上传还是文件下载,一个完整的案例大致都需要这样一个过程:

    • 构思需求和页面大体样式
    • 编写前端html页面
    • 编写服务端响应的请求
    • 启动程序运行测试

    在其中过程如果有问题可以根据编译器的错误提示、运行时的错误日志找到根源进行修正,这样完整的案例就可以成功完成啦!

    案例拓展

    你是否觉得自己掌握的可以了?那好,咱们拓展提升一下,我给你来一个需求:单文件和多文件混合上传

    假设小明需要实现一个文件上传功能,小明需要上传一份简历和若干份照片(小于3)。这个项目该如何设计呢?它的计划页面可能是这样的:

    在这里插入图片描述

    我觉得聪明的你一定不会被难住,对于前端界面的html有什么想法呢?

    对于种类来说有简历和照片两种文件,对于它们各自来说,简历只有一份,而照片可能有多份。

    那么咱们的html页面可以这样设计:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>个人信息上传</title>
    </head>
    <body>
    <h2>个人信息上传</h2>
    <form name="onfile"  action="infoupload" method="post" enctype="multipart/form-data">
        姓名:<input type="text" name="name" ><br>
        年龄:<input type="text" name="age"> <br>
        图片:<input type="file" name="img">
             <input type="file" name="img">
        简历:<input type="file" name="resume"><br>
        <input type="submit" value="提交">
    </form>
    </body>
    </html>
    
    

    这里面和前面的单文件上传不同的是有多个input标签,此外action也要改成infoupload意思是你需要写这么一个接口来处理这个文件上传的内容。在controller中编写以下代码:

     private  static Logger logger= LoggerFactory.getLogger(uploadController.class);
        @PostMapping("infoupload")
        @ResponseBody
        public String onfile(String name,String age, MultipartFile img[],MultipartFile resume) throws IOException {
            logger.info(name);//日志中打印传输的name
            logger.info(age);
            //接收img[]
            for(int i=0;i<img.length;i++)
            {
                if(!img[i].isEmpty())//文件不空
                {
                    File imgfile =new File("F:/fileupload/"+img[i].getOriginalFilename());
                    imgfile.createNewFile();
                    img[i].transferTo(imgfile);
                }
            }
             //接收resume
            File resumefile =new File("F:/fileupload/"+resume.getOriginalFilename());
            //在磁盘中创建文件,此时文件存在但没有内容
            resumefile.createNewFile();
            //将接受的文件复制到创建的文件中
            resume.transferTo(resumefile);
            return "sucucess";
        }
    
    

    这个理解起来其实也很容易,这个和上面主要的区别就是函数中的多参数,其实每一个参数都是要和前端页面的form表单input标签的内容对应(名称一致)。form表单中的file类型在Springmvc的controller中就是对应MultipartFile类型,form表单中的text类型对应controller中的String类型。如果上传单个文件,在服务端就用MultipartFile类型参数接收,如果多文件就用MultipartFile[]进行接收。上传类型和个数根据你自己的需求设计定义。

    我们启动程序打开浏览器输入http://localhost:8080/index4.html选择文件进行上传,然后在本地你可以看到文件成功被保存。

    在这里插入图片描述

    至此,本篇的内容就结束了,本文主要简单讲解了Springmvc中文件上传、多文件上传、文件下载的实现,现在你已熟练掌握。青山不改,绿水长流,我们下期再见!下课!

    博主微信公众号:bigsai 一个等你关注而朝思夜暮的程序猿。
    在这里插入图片描述

    展开全文
  • JFinal文件上传下载

    千次阅读 2016-12-12 09:10:20
    JFinal的文件上传下载(个人整理)
  • Python Flask文件上传下载

    千次阅读 2020-02-13 20:03:16
    Flask文件上传下载 上传文件 html代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>上传文件</title> </head> <body> <div>...
  • springboot文件上传下载

    千次阅读 2017-08-20 16:09:05
    文件上传下载是web服务经常使用的功能。但实际使用过程中,也有一些需要注意的地方。本文结合实际代码说明一下。 1.添加maven依赖: commons-fileupload commons-fileupload 1.3.2 commons-io ...
  • SpringBoot实现简单的文件上传下载

    千次阅读 2021-01-19 18:14:08
    SpringBoot实现简单的文件上传下载 文章目录SpringBoot实现简单的文件上传下载1、新建一个SpringBoot的项目1.1、新建项目1.2、配置pom.xml文件2、写代码2.1、编写FileController,实现文件上传下载2.2、编写...
  • JavaWeb 文件 上传 下载

    千次阅读 多人点赞 2016-07-30 21:49:29
    文件上传下载对于一个网站来说,重要性不言而喻。今天来分享一个JavaWeb方式实现的文件上传下载的小例子。项目依赖这个小例子是使用JavaWeb的JSP+Servlet实现的。另外使用了一些第三方的jar包。现列举如下: apache-...
  • Java文件上传下载

    千次阅读 2016-04-21 08:23:42
    Java文件上传下载在上传图片之前,预览图片,可参考Preview an image before it is uploaded基本原理文件上传原理通过为表单元素设置Method="post" enctype="multipart/form-data"属性,让表单提交的数据以二进制...
  • 里面包含了文件上传下载并解决上传与下载文件中文乱码的问题,运用正则表达式判断字符串中是否包含中文和得到一个文件夹下的所有文件的方法,几乎集合了上传下载所需要的所有东西.下面代码加红的部分就是这几个重要点!...
  • python实现文件上传下载

    万次阅读 2018-05-29 18:55:17
    Python实现文件上传下载 环境准备: 1. 实验分两个文件,服务端(linux)和客户端(windows). 服务端运行环境:python2.x 客户端运行环境:python3.x 2. 使用了库socket和os 客户端代码: import socket # ...
  • SpringBoot文件上传下载

    万次阅读 2018-04-10 10:04:17
    项目中经常会有上传下载的需求,这篇文章简述一下springboot项目中实现简单的上传下载。 新建springboot项目,前台页面使用的thymeleaf模板,其余的没有特别的配置,pom代码如下: &lt;?xml version=&...
  • spring springboot webflux 文件上传下载

    千次阅读 2019-01-17 16:19:23
    webflux 的文件上传下载功能 文件上传 先上代码 @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public Mono&lt;String&gt; requestBodyFlux(@RequestPart(&...
  • jsp实现文件上传下载功能

    万次阅读 多人点赞 2019-01-27 22:07:47
    文件上传首先得引入两个jar包,建议在mvn库中下载下载完粘贴到lib目录下 首先写上传文件的jsp界面 &lt;form action="UpLoadServet" method="post" enctype="multipart/form-...
  • springboot实现文件上传下载功能

    千次阅读 2020-02-27 14:58:00
    SpringBoot实现文件上传下载功能 开发环境 - SpringBoot 2.2.1.RELEASE - web依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web<...
  • 阿里对象存储 OSS 文件上传下载,图片上传java前言创建oss 空间购买流量获取Access Key文件上传和下载安装sdk上传下载图片上传和遍历图片上传遍历endpoint 一定要看这个,记着这个词,看这个 前言 本文章文字介绍...
  • SpringBoot实现文件上传下载的功能

    万次阅读 多人点赞 2017-05-23 01:00:12
    SpringBoot我们大多数的时候是当做服务提供者来使用的,但是在一些场景中还是要用到一些文件上传下载这种"非常规"操作的。那么怎么在SpringBoot中实现文件的上传下载功能呢?想象一些我们在SpringMVC中是怎么做的。...
  • FTP文件上传下载及验证

    千次阅读 2016-05-09 18:25:10
    FTP文件上传下载及验证有时候经常用到FTP的上传下载,本身代码相对比较简单,但有时需要考虑到文件上传下载进行验证。大体思路是上传时将FTP日志重定向到本地文件,再根据FTP返回码进行检查,这样有个缺点就是不能...
  • .Net Core 图片文件上传下载

    千次阅读 2017-06-19 21:06:23
    当下.Net Core项目可是如雨后春笋一般发展起来,作为.Net大军中的一员,我热忱地拥抱了.Net Core并且积极使用其进行业务的开发,我们先介绍下.Net Core项目下实现文件上传下载接口。 一、开发环境 毋庸置疑,...
  • FastDFS实现文件上传下载实战

    万次阅读 热门讨论 2016-11-20 20:39:16
    正好,淘淘商城讲这一块的时候,我又想起来当时老徐让我写过一个关于实现FastDFS实现文件上传下载的使用文档,当时结合我们的ITOO的视频系统和毕业论文系统,整理了一下,有根据网上查到的知识,总结了一点东西,...
  • JavaWeb实现简单的文件上传下载

    千次阅读 2016-05-16 20:47:39
    javaweb,文件上传下载
  • Java文件上传下载删除(下载中文乱码问题)
  • iOS 实现文件上传下载

    千次阅读 2013-04-16 15:19:17
    iOS开发中会经常用到文件上传下载的功能,这篇文件将介绍一下使用asp.net webservice实现文件上传下载。 首先,让我们看下文件下载。 这里我们下载cnblogs上的一个zip文件。使用NSURLRequest+NSURLConnection可以...
  • struts2教程--实现文件上传下载

    千次阅读 2017-04-18 17:02:33
    Struts2文件上传下载 一、Struts2文件上传 提供 FileUpload 拦截器,用于解析 multipart/form-data 编码格式请求,解析上传文件的内容 fileUpload拦截器 默认在 defaultStack 栈中, 默认会执行的   在Action...
  • SSM文件上传下载

    千次阅读 2019-06-10 16:34:59
    SSM上传下载上传 上传 上传文件的基本要求: 1、form表单提交必须是post请求:method="post" 2、添加enctype属性:enctype="multipart/form-data
  • React中使用fetch实现文件上传下载

    千次阅读 2018-11-18 20:58:45
    在最近的项目中需要实现文件上传下载功能,在以前spring、jsp的项目中实现文件上传很简单,但现在前后端分离,前端使用React,后端使用Spring Boot,实现就没那么方便了。 前端React使用fetch而非传统的...
  • python flask简单文件上传下载实现

    千次阅读 2019-06-25 14:04:07
    功能:用python+flask实现简单的文件上传下载,并简单过滤下文件名的“.”和“/”,同时对文件名进行通过uuid重命名,存到服务器上,并将原文件名、重命名等信息保存到db中,需要时从db查询出来还原即可 PS:适合单...
  • Spring Boot实现SFTP文件上传下载

    千次阅读 2019-04-25 13:12:41
    Spring Boot实现SFTP文件上传下载 1.实现背景及现实意义 近期由于系统迁移到docker容器,采用Spring Boot 框架实现微服务治理,在此基础上晚间批量文件服务器也由ftp改成sftp,由于之前ftp的实现是采用公具类的...
  • koa文件上传下载

    千次阅读 2018-07-31 17:10:50
    上传下载在web应用中是比较常见的,无论是图片还是其他文件。在koa2中,我们可以使用中间件帮助我们快速实现功能 文件上传 在前端上传文件,我们都是通过表单来上传,而上传文件,在服务器端并不能像普通参数一样...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 91,114
精华内容 36,445
关键字:

文件上传下载