实现下载
修改server.xml
修改web.xml
 
实现上传
实现客户端的上传
post请求
代码实现
实现服务端的处理
 
小结
 
 
 
 
实现下载
实现下载需要
 - 修改Tomcat中的server.xml
 - 修改web.xml
 
修改server.xml
在<Host> </Host>中加入(一般在文件末尾可以找到)
 
<Context docBase="C://Download" path="/download" reloadable="true" />1
其中docBase项是本地目录,path项是访问目录
 
修改web.xml
 
   <servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>true</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>12345678910111213
其中listings下确保值是true
这时在C://Download下存放文件,并打开相应的地址,就能看见文件目录了
 
实现上传
实现上传也是分两步
实现客户端的上传
实现服务端的处理
 
实现客户端的上传
 
post请求
我们都知道http常用的请求方式有get、post等,其中我们实现文件上传,就是模拟表单采用post方式上传文件
首先来看一下post报文的格式,以上传一张图片为例
 
POST/logsys/home/uploadIspeedLog!doDefault.html HTTP/1.1
Accept: text/plain, */*
Accept-Language: zh-cn
Host: 192.168.24.56
Content-Type:multipart/form-data;boundary=【这里随意设置】
User-Agent: WinHttpClient
Content-Length: 3693
Connection: Keep-Alive123456789
以上部分是请求的参数,不需要我们完全实现,通过方法传参的方式自动构建
 
--【这里随意设置】
Content-Disposition: form-data;name="file1";filename="C://E//a.png"
Content-Type:application/octet-stream
<文件的二进制信息>
--【这里随意设置】--1234567
这一部分是报文的内容,需要我们通过字符串或者字节流自行拼接,并且格式不能出错
  注意,三处【这里随意设置】的部分必须完全相同
 
代码实现
 
public static void uploadFile(String fileName) { 
    try { 
        // 换行符 
        final String newLine = "\r\n"; 
        //数据分隔线 
        final String BOUNDARY = "【这里随意设置】";//可以随意设置,一般是用  ---------------加一堆随机字符
        //文件结束标识
        final String boundaryPrefix = "--"; 
        // 服务器的域名 
        URL url = new URL("http://localhost:8070/secondary/HandleFile"); 
        HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 
        // 设置为POST情 
        conn.setRequestMethod("POST"); 
        // 发送POST请求必须设置如下两行 
        conn.setDoOutput(true); 
        //conn.setDoInput(true);/不必加,默认为true 
        //conn.setUseCaches(false);//用于设置缓存,默认为true,不改也没有影响(至少在传输单个文件这里没有) 
        // 设置请求头参数 
        //关于keep-alive的说明:https://www.kafan.cn/edu/5110681.html
        //conn.setRequestProperty("connection", "Keep-Alive");//现在的默认设置一般即为keep-Alive,因此此项为强调用,可以不加
        //conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows Nt 5.1; SV1)");//用于模拟浏览器,非必须
        //用于表示上传形式,必须
        conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY); 
        //这里是Charset,网上大多都是Charsert???我的天,笑哭。不过好像没什么影响...不知道哪位大佬解释一下
        conn.setRequestProperty("Charset", "UTF-8");
        //获取conn的输出流用于向服务器输出信息
        OutputStream out = new DataOutputStream(conn.getOutputStream()); 
        //构造文件的结构 
        //写参数头
        StringBuilder sb = new StringBuilder(); 
        sb.append(boundaryPrefix)//表示报文开始
          .append(BOUNDARY)//添加文件分界线
          .append(newLine);//换行,换行方式必须严格约束
        //固定格式,其中name的参数名可以随意修改,只需要在后台有相应的识别就可以,filename填你想要被后台识别的文件名,可以包含路径
        sb.append("Content-Disposition: form-data;name=\"file\";")
            .append("filename=\"").append(fileName)
            .append("\"")
            .append(newLine); 
        sb.append("Content-Type:application/octet-stream"); 
        //换行,为必须格式
        sb.append(newLine); 
        sb.append(newLine); 
        //将参数头的数据写入到输出流中 
        out.write(sb.toString().getBytes()); 
        System.out.print(sb);
        //写文件数据(通过数据输入流) 
        File file = new File(fileName);
        DataInputStream in = new DataInputStream(new FileInputStream( 
                file)); 
        byte[] bufferOut = new byte[1024]; 
        int bytes = 0; 
        //每次读1KB数据,并且将文件数据写入到输出流中 
        while ((bytes = in.read(bufferOut)) != -1) { 
            out.write(bufferOut, 0, bytes); 
        } 
        in.close();
        //写参数尾 
        out.write(newLine.getBytes()); 
        System.out.print(new String(newLine.getBytes()));
        // 定义最后数据分隔线,即--加上BOUNDARY再加上--。
        sb = new StringBuilder();
        sb.append(newLine)
            .append(boundaryPrefix)
            .append(BOUNDARY)
            .append(boundaryPrefix)
            .append(newLine);
        // 写上结尾标识 
        out.write(sb.toString().getBytes()); 
        System.out.println(sb);
        //输出结束,关闭输出流
        out.flush(); 
        out.close(); 
        //定义BufferedReader输入流来读取URL的响应 ,注意必须接受来自服务器的返回,否则服务器不会对发送的post请求做处理!!这里坑了我好久
        BufferedReader reader = new BufferedReader(new InputStreamReader( 
                conn.getInputStream())); 
        String line = null; 
        while ((line = reader.readLine()) != null) { 
            System.out.println(line); 
        } 
    } catch (Exception e) { 
        System.out.println("发送POST请求出现异常!" + e); 
        e.printStackTrace(); 
    } 

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
注释很清楚,结合post请求的格式理解一下,就不一一解释了
 
实现服务端的处理
上述的代码会形成一个post请求到服务器,于是相应的接口的dopost()方法就会相应
dopost()中做了什么呢?
获取报文中的文件信息
处理文件信息,包括识别文件名,识别文件类型(由用户定义,而不是文件后缀)
存储到本地(服务器端硬盘)
代码如下:
 
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
//注意导的包
/**
 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
 */
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.setCharacterEncoding("UTF-8");
    request.setCharacterEncoding("UTF-8");
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    //输出到客户端浏览器
    DiskFileItemFactory factory = new DiskFileItemFactory();
    ServletFileUpload sup = new ServletFileUpload(factory);//这里要将factory传入,否则会报NullPointerException: No FileItemFactory has been set.
    try{
        List<FileItem> list = sup.parseRequest(request);
        for(FileItem fileItem:list){
            System.out.println(fileItem.getFieldName()+"--"+fileItem.getName());
            if(!fileItem.isFormField()){
                if("file".equals(fileItem.getFieldName())){
                    //获取远程文件名
                    String remoteFilename = new String(fileItem.getName().getBytes(),"UTF-8");
                    File remoteFile = new File(remoteFilename);
                    //设置服务器端存放文件的位置
                    File locate = new File("C://E//download/",remoteFile.getName());
//                      locate.getParentFile().mkdirs();//用于确保文件目录存在,如果为单级目录可以去掉
                    locate.createNewFile(); //创建新文件
                    InputStream ins = fileItem.getInputStream();   //FileItem的内容
                    OutputStream ous = new FileOutputStream(locate); //输出
                    try{
                        byte[] buffer = new byte[1024]; //缓冲字节
                        int len = 0;
                        while((len = ins.read(buffer))>-1)
                            ous.write(buffer, 0, len);
                    }finally{
                        ous.close();
                        ins.close();
                    }
                }
            }      
        }
    }catch (FileUploadException e){}
    out.print("everything is ok");
    out.flush();
    out.close();
}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
同样注释很清楚,不再解释了
小结
将上述过程理解清楚后,再结合post报文的格式,那么是否就可以处理多个文件同时上传了呢?如果对客户端的流做出一些大小限制,是不是就可以限制上传大小了?…一个小demo,帮助理解一下基础的实现。
---------------------
作者:Sailist
来源:CSDN
原文:https://blog.csdn.net/sailist/article/details/81083205
版权声明:本文为博主原创文章,转载请附上博文链接!

tomcat实现文件上传下载的更多相关文章

  1. SpringMVC文件上传下载

    在Spring MVC的基础框架搭建起来后,我们测试了spring mvc中的返回值类型,如果你还没有搭建好springmvc的架构请参考博文->http://www.cnblogs.com/q ...

  2. 阿里云负载均衡SLB的文件上传下载问题解决

    Nfs同步文件夹配置 问题描述 : javaweb应用部署到云服务器上时,当服务器配置了SLB负载均衡的时候,多台服务器就会造成文件上传下载获取不到文件的错误, 解决办法有:1.hdfs  2.搭建f ...

  3. 17.[CVE-2017-12615]Tomcat任意文件上传漏洞

    [CVE-2017-12615] Tomcat任意文件上传漏洞 首先先贴出wooyun上的一个案例:http://wooyun.jozxing.cc/static/bugs/wooyun-2015-0 ...

  4. Spring Boot2(十四):单文件上传/下载,文件批量上传

    文件上传和下载在项目中经常用到,这里主要学习SpringBoot完成单个文件上传/下载,批量文件上传的场景应用.结合mysql数据库.jpa数据层操作.thymeleaf页面模板. 一.准备 添加ma ...

  5. SpringMVC文件上传下载(单文件、多文件)

    前言 大家好,我是bigsai,今天我们学习Springmvc的文件上传下载. 文件上传和下载是互联网web应用非常重要的组成部分,它是信息交互传输的重要渠道之一.你可能经常在网页上传下载文件,你可能 ...

  6. SpringBoot入门一:基础知识(环境搭建、注解说明、创建对象方法、注入方式、集成jsp/Thymeleaf、logback日志、全局热部署、文件上传/下载、拦截器、自动配置原理等)

    SpringBoot设计目的是用来简化Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置.通过这种方式,SpringBoot致力于在蓬勃发 ...

  7. Struts的文件上传下载

    Struts的文件上传下载 1.文件上传 Struts2的文件上传也是使用fileUpload的组件,这个组默认是集合在框架里面的.且是使用拦截器:<interceptor name=" ...

  8. Android okHttp网络请求之文件上传下载

    前言: 前面介绍了基于okHttp的get.post基本使用(http://www.cnblogs.com/whoislcj/p/5526431.html),今天来实现一下基于okHttp的文件上传. ...

  9. Selenium2学习-039-WebUI自动化实战实例-文件上传下载

    通常在 WebUI 自动化测试过程中必然会涉及到文件上传的自动化测试需求,而开发在进行相应的技术实现是不同的,粗略可划分为两类:input标签类(类型为file)和非input标签类(例如:div.a ...

随机推荐

  1. 深入理解Flink核心技术及原理

    前言 Apache Flink(下简称Flink)项目是大数据处理领域最近冉冉升起的一颗新星,其不同于其他大数据项目的诸多特性吸引了越来越多人的关注.本文将深入分析Flink的一些关键技术与特性,希望 ...

  2. MySQL 索引最佳实践

    原文请关注 这里 这是 文章 的翻译,在翻译过程中,会对其中涉及到的语句加上一些个人理解以及 SQL 语句的执行,并进行特别的标注. 1. 你做了一个很棒的选择,因为: 对于普通开发者和 DBA,理解 ...

  3. SSM整合-配置文件

    使用工具:maven.idea.jdk8.mysql.tomcat9.0 初学ssm框架,配置文件的配置目录:                                     其中genera ...

  4. oracle加密--wallet

    SQL> SELECT * FROM V$ENCRYPTION_WALLET; WRL_TYPE WRL_PARAMETER STATUS -------------------- ------ ...

  5. PAT(B) 1053 住房空置率(Java)统计

    题目链接:1053 住房空置率 (20 point(s)) 题目描述 在不打扰居民的前提下,统计住房空置率的一种方法是根据每户用电量的连续变化规律进行判断.判断方法如下: 在观察期内,若存在超过一半的 ...

  6. zabbix的离线安装方法----孙祎晨,如需转载请注明出处,谢谢配合。

    ------------------------zabbix的离线安装步骤--------------------------------------------------------------- ...

  7. 用ASP.NET Web API技术开发HTTP接口(二)

    在第一部分,我们创建了一个基本的ASP.NET Web API项目,新建成功了数据表,然后添加了一些测试数据,最后创建了API控制器,用json格式把数据表里面的内容成功输出到浏览器上.接下来我们将继 ...

  8. hdu1501 记忆化搜索。。。

    Problem Description Given three strings, you are to determine whether the third string can be formed ...

  9. VS.NET(C#)--2.1认识控件

    Web控件 四种控件 1.HTML控件 2.HTML服务器控件    在服务器端执行 3.ASP.NET服务器控件   在服务器端执行 4.用户控件和自定义控件  用户自定义控件在服务器端执行 注意: ...

  10. java.lang.NoClassDefFoundError: org/springframework/core/env/EnvironmentCapa

    java.lang.NoClassDefFoundError: org/springframework/core/env/EnvironmentCapa 少导入包!spring-core-*.jar ...