【文件上传和下载】是很多系统必备功能, 比如PM\OA\ERP等;系统中常见的开发模式有B/S和C/S,而前者主要是通过浏览器来访问web服务器,一般采用七层协议中的【应用层http】进行数据传输,后者主要通过编程语言开发的app作为客户端来访问服务端,一般采用七层协议中的【传输层tcp】进行数据传输。
文章主要完成简单java web涉及的文件上传和下载功能。

正文

1. java原生servlet实现:

pom.xml配置:
<dependency>
      <groupId>javax</groupId>
      <artifactId>javaee-api</artifactId>
      <version>8.0</version>
      <scope>provided</scope>
</dependency>
<dependency>
      <groupId>javax</groupId>
      <artifactId>javaee-web-api</artifactId>
      <version>8.0</version>
      <scope>provided</scope>
</dependency>
<dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.</version>
      <scope>runtime</scope>
</dependency>
web.xml配置:
<welcome-file-list>  
    <welcome-file>/WEB-INF/view/jsp/upload/upload.jsp</welcome-file>
</welcome-file-list>
<!-- 声明Servlet对象 -->
<servlet>
    <!-- 指定Servlet对象的名称 -->
    <servlet-name>UploadServlet</servlet-name>
    <!-- 指定Servlet对象的完整位置,包含包名和类名 -->
    <servlet-class>pers.chaffee.servlet.UploadServlet</servlet-class>
</servlet>
<!-- 映射Servlet -->
<servlet-mapping>
    <!--<servlet-name>与上面<Servlet>标签的<servlet-name>元素相对应,不可以随便起名  -->
    <servlet-name>UploadServlet</servlet-name>
    <!-- 用于映射访问URL -->
    <url-pattern>/UploadFileServlet</url-pattern>
</servlet-mapping>
servlet实现:
@WebServlet("/UploadServlet")
public class UploadServlet extends HttpServlet {

@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) {

//根据文件扩展名设置文件MIME类型
        resp.setContentType(getServletContext().getMimeType("hello.txt"));

//设置下载消息响应,提示文件保存attachment
        resp.setHeader("Content-Disposition", "attachment;filename=" + "hello");

/*
         * 设置缓冲区
         * is.read(b)当文件读完时返回-1
         */
        try {
            //输入流为项目文件,输出流指向浏览器
            InputStream is = new FileInputStream("E:\\hello.txt");

// 提供了将二进制数据写入响应的流
            ServletOutputStream os = resp.getOutputStream();

int len = -1;
            byte[] b = new byte[1024];
            while ((len = is.read(b)) != -1) {
                os.write(b, 0, len);
            }
            //关闭流
            is.close();
            os.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

@Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
        // 文件上传到本地磁盘工厂类
        DiskFileItemFactory factory = new DiskFileItemFactory();
        //设置内存缓冲区的大小
        factory.setSizeThreshold(20480);
        //设置临时文件目录,供上传文件过大时临时存储
        factory.setRepository(new File("F:\\f"));

//文件上传操作核心类
        ServletFileUpload upload = new ServletFileUpload(factory);
        //设置限制单个上传文件的大小
        upload.setFileSizeMax(50480);
        //设置限制总上传文件大小
        upload.setSizeMax(80480);
        // 这个路径相对当前应用的目录
        try {
            List<FileItem> formItems = upload.parseRequest(req);
            if (formItems != null && formItems.size() > 0) {
                // 迭代表单数据
                for (FileItem item : formItems) {
                    // 处理不在表单中的字段
                    if (!item.isFormField()) {
                        File storeFile = new File("F:\\fromweb_" + item.getName());
                        // 保存文件到硬盘
                        item.write(storeFile);
                    }
                }
            }
        } catch (FileUploadException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
upload.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>文件上传实例</h1>
<!--请求编码类型必须为"multipart/form-data"-->
<form method="post" action="/UploadFileServlet" enctype="multipart/form-data">
    选择一个文件:
    <input type="file" name="uploadFile"/>
    <input type="file" name="uploadFile2"/>
    <br/><br/>
    <input type="submit" value="上传"/>
</form>
<a href="/UploadFileServlet" rel="nofollow">下载</a>
</body>
</html>
2. java web主流框架【ssm】实现:

pom.xml配置
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>${spring.version}</version>
</dependency>
web.xml配置
<context-param>
    <param-name>contextConfigLocation</param-name>
    <!--<param-value>classpath*:applicationContext-*.xml</param-value>-->
    <param-value>classpath*:*.xml</param-value>
</context-param>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
    <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
<servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/service/*</url-pattern>
</servlet-mapping>
spring-mvc.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans  
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd  
        http://www.springframework.org/schema/context  
        http://www.springframework.org/schema/context/spring-context-3.2.xsd  
        http://www.springframework.org/schema/mvc  
        http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">

<!-- 启动SpringMVC的注解功能 -->
    <mvc:annotation-driven/>

<!-- 扫描controller(controller层注入) -->
    <context:component-scan base-package="pers.chaffee.controller"/>

<!-- 对模型视图添加前后缀 -->
    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          p:prefix="/WEB-INF/view/jsp/" p:suffix=".jsp"/>

<!-- 静态资源不走controller -->
    <mvc:resources mapping="/resources/**" location="/resources/"/>
</beans>  
servlet实现:
    @RequestMapping(value = "/upload2", method = RequestMethod.POST, consumes = {"multipart/form-data"})
    public ModelAndView postUpload(HttpServletRequest request, HttpServletResponse response) {
        
        //文件上传核心类
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
        
        //判断request是否有文件上传
        if (multipartResolver.isMultipart(request)) {
            //通过MultipartHttpServletRequest解析上传请求中的文件
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            //获取上传请求中的所有文件
            Iterator<String> iter = multiRequest.getFileNames();
            while (iter.hasNext()) {
                //转换成spring支持的文件类型MultipartFile
                MultipartFile file = multiRequest.getFile(iter.next());
                if (file != null) {
                    File localFile = new File("F:\\f\\" + file.getOriginalFilename());
                    try {
                        //将上传文件写到指定位置,此处是本地文件夹
                        file.transferTo(localFile);
                    } catch (IllegalStateException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("upload/upload2");
        return modelAndView;
        }
    
    @RequestMapping(value = "/download", method = RequestMethod.GET)
    public ResponseEntity<byte[]> downLoad() throws IOException {
        byte[] responseBody;
        //获取文件
        File file = new File("E:\\hello.txt");
        InputStream is = new FileInputStream(file);
        responseBody = new byte[is.available()];
        is.read(responseBody);
        HttpHeaders headers = new HttpHeaders();
        
        //设置文件类型
        headers.add("Content-Disposition", "attachment;filename=" + file.getName());
        
        //设置Http状态码
        HttpStatus stateCode = HttpStatus.OK;
        
        //返回数据
        ResponseEntity<byte[]> entity = new ResponseEntity<>(responseBody, headers, stateCode);
        return entity;
    }
小结

截至目前,只初步完成B/S方式的上传和下载,且文件存储方式仅限本地磁盘。而C/S方式的文件传输可以考虑thrift框架,thrift是一种跨平台跨语言的RPC框架,使用过程中发现在数据量不是很大的情况下thrift应用是一种比较合适的C/S解决方案;另外,文件存储方式可以根据具体情况选用文件服务器、数据库等。

详细的配置信息可以参考这篇文章:

http://blog.ncmem.com/wordpress/2019/08/12/java%e5%ae%9e%e7%8e%b0%e5%a4%a7%e6%96%87%e4%bb%b6%e4%b8%8a%e4%bc%a0%e5%92%8c%e4%b8%8b%e8%bd%bd/

java实现大文件上传和下载的更多相关文章

  1. java+web+大文件上传下载

    文件上传是最古老的互联网操作之一,20多年来几乎没有怎么变化,还是操作麻烦.缺乏交互.用户体验差. 一.前端代码 英国程序员Remy Sharp总结了这些新的接口 ,本文在他的基础之上,讨论在前端采用 ...

  2. 【原创】用JAVA实现大文件上传及显示进度信息

    用JAVA实现大文件上传及显示进度信息 ---解析HTTP MultiPart协议 (本文提供全部源码下载,请访问 https://github.com/grayprince/UploadBigFil ...

  3. Nginx集群之WCF大文件上传及下载(支持6G传输)

    目录 1       大概思路... 1 2       Nginx集群之WCF大文件上传及下载... 1 3       BasicHttpBinding相关配置解析... 2 4       编写 ...

  4. 全网最简单的大文件上传与下载代码实现(React+Go)

    前言 前段时间我需要实现大文件上传的需求,在网上查找了很多资料,并且也发现已经有很多优秀的博客讲了大文件上传下载这个功能. 我的项目是个比较简单的项目,并没有采用特别复杂的实现方式,所以我这篇文章的目 ...

  5. Java实现FTP文件上传与下载

    实现FTP文件上传与下载可以通过以下两种种方式实现(不知道还有没有其他方式),分别为:1.通过JDK自带的API实现:2.通过Apache提供的API是实现. 第一种方式 package com.cl ...

  6. 用JAVA实现大文件上传及显示进度信息

    一. 大文件上传基础描述: 各种WEB框架中,对于浏览器上传文件的请求,都有自己的处理对象负责对Http MultiPart协议内容进行解析,并供开发人员调用请求的表单内容. 比如: Spring 框 ...

  7. 【Java】JavaWeb文件上传和下载

    文件上传和下载在web应用中非常普遍,要在jsp环境中实现文件上传功能是非常容易的,因为网上有许多用java开发的文件上传组件,本文以commons-fileupload组件为例,为jsp应用添加文件 ...

  8. java支持断点续传文件上传和下载组件

    java两台服务器之间,大文件上传(续传),采用了Socket通信机制以及JavaIO流两个技术点,具体思路如下: 实现思路: 1.服:利用ServerSocket搭建服务器,开启相应端口,进行长连接 ...

  9. PHP实现大文件上传和下载

    一提到大文件上传,首先想到的是啥??? 没错,就是修改php.ini文件里的上传限制,那就是upload_max_filesize.修改成合适参数我们就可以进行愉快的上传文件了.当然啦,这是一般情况下 ...

随机推荐

  1. Scratch 3.0,新在哪里?

    大家期待已久的Scratch 3.0,已经上线一段时间了. 学生们可轻松通过连接WeDo2.0和EV3机器人 进行scratch编程学习啦! 或许有些朋友还不太了解Scratch,没关系,小乐今天就为 ...

  2. 关于arm 的字节对齐

    一.什么是字节对齐,为什么要对齐? 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这 ...

  3. MarkdownPad2安装与破解-转载

    MarkdownPad安装包下载链接链接:https://pan.baidu.com/s/1o7c4W7C2d8zCPh5z7y4IvQ提取码:e4bf 下载解压之后,找要MarkdownPad2.e ...

  4. (八)二进制文件在webservice中的处理(以byte[]字节数组方式)

    一.介绍 二进制文件在webservice中的处理. A:通过byte[]字节数组的方式来传递.比较适合小文件,字节数组不能太大的情况.(本章所用) B:通过DataHander的方式来进行传递. 1 ...

  5. c#获取本月有哪些周六、周日

    最近项目中有用到本月所有的周六,周日,特此分享一下! 算法思路:写一个循环,条件为本月开始日期.本月截至日期,通过循环获取第一个周六,加一天就是周日,每增加六天就是下一个周六,依次类推,循环到月末 代 ...

  6. Html 中scroll offset client 总结

    HTML精确定位:scrollLeft,scrollWidth,clientWidth,offsetWidth scrollHeight: 获取对象的滚动高度. scrollLeft:设置或获取位于对 ...

  7. [JZOJ5897]密匙--哈希骚操作

    [JZOJ5897]密匙--哈希骚操作 题目链接 太懒了自行Google 前置技能 二分/倍增求LCP e.g TJOI2017DNA 分析 这题看了样例解释才知道什么意思 本以为自己身为mo法师蛤希 ...

  8. 初学java1 数据类型

    java数据类型 分为8种 整型 byte 8位 short 16位 int 32位 long 64位 字符型 char 必需为单引号'' 且只能有一个字符 浮点型 float double 布尔类型 ...

  9. Django入门第一步:构建一个简单的Django项目

    Django入门第一步:构建一个简单的Django项目 1.简介 Django是一个功能完备的Python Web框架,可用于构建复杂的Web应用程序.在本文中,将通过示例跳入并学习Django.您将 ...

  10. Idea查看一个类和子类(实现类)的结构图

    选择一个类:右键选择Diagrams-show Diagrams(show Diagrams popup表示悬浮当前窗口) 进入下面类似下面的界面: 如果想查看某个类或接口的子类: 先查看自己本地设置 ...