【文件上传和下载】是很多系统必备功能, 比如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. SVM的概率输出(Platt scaling)

    SVM的概率输出(Platt scaling) 2015-10-22 10:38:19 闲渔Love吉他 阅读数 8121 文章标签: Platt Scaling Calibr 更多 分类专栏: 计算 ...

  2. 在论坛中出现的比较难的sql问题:5(row_number函数 分页、随机返回数据)

    原文:在论坛中出现的比较难的sql问题:5(row_number函数 分页.随机返回数据) 所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路. 1.在inner join后, ...

  3. C# 中类的成员有哪些?

    类(class)是C#类型中最基础的类型.类是一个数据结构,将状态(字段)和行为(方法和其他函数成员)组合在一个单元中.类提供了用于动态创建类实例的定义,也就是对象(object).类支持继承(inh ...

  4. Sublime Text 添加java环境

    jre/bin/ 目录下添加 runJava.bat @ECHO OFF cd %~dp1 ECHO Compiling %~nx1....... IF EXIST %~n1.class ( DEL ...

  5. Junit 学习1 junit的简单使用

    package junit; import java.sql.Connection; import java.sql.SQLException; import org.junit.Test; impo ...

  6. HTML中关于 浮动 的简单说明

    1.首先,标签之所以有存在等级分类,是因为他们处于标准文档流(块级元素,行内元素,行内块元素)当中. 2.如何脱离标准文档流? 浮动 绝对定位 固定定位 这些可以让一个标签脱离标准文档流,而元素一旦脱 ...

  7. MyCAT详解【转】

    原文链接:MyCAT详解 作者:Rangle 一.MyCAT概述MyCAT是一款由阿里Cobar演变而来的用于支持数据库读写分离.分片的分布式中间件.MyCAT可不但支持Oracle.MSSQL.MY ...

  8. iOS8中UIActionSheet弹出UIImagePickerController异常处理

    iOS8之后,UIActionSheet改父于UIAlertController.带来了一丢丢兼容性的问题. 比如在弹出的actionsheet中选择从相册选择图片或者拍照,之后弹出UIImagePi ...

  9. oracle 如何将带有,的一列分成多列

    select regexp_substr('1,2,3' , '[^,]+' , 1 , ROWNUM) FROM dual CONNECT BY ROWNUM<=LENGTH('1,2,3') ...

  10. OSI七层与TCP/IP五层

    OSI七层与TCP/IP五层网络架构详解 OSI和TCP/IP是很基础但又非常重要的网络基础知识,理解得透彻对运维工程师来说非常有帮助.今天偶又复习了一下: (1)OSI七层模型 OSI中的层 功能 ...