详细分析java中文件的上传与下载(servlet与流行框架)

在开发过程中文件的上传下载很常用。这里简单的总结一下:

1.文件上传必须满足的条件:
a、 页面表单的method必须是post 因为get传送的数据太小了
b、 页面表单的enctype必须是multipart/form-data类型的
c、 表单中提供上传输入域
代码细节: 客户端表单中:<form enctype="multipart/form-data"/>
(如果没有这个属性,则服务端读取的文件路径会因为浏览器的不同而不同)
服务端ServletInputStream is=request.getInputStream();用流的方式获取请求正文内容,进一步的解析。

这里写图片描述

2.上传文件的细节:
(1)为什么设置表单类型为:multipart/form-data.是设置这个表单传递的不是key=value值。传递的是字节码.
表单与请求的对应关系:
这里写图片描述
如上可以看出在设置表单类型为:multipart/form-data之后,在HTTP请求体中将你选择的文件初始化为二进制,如上图中的Cookie之下的一串的随机字符串下的内容。
但注意,在标识文件(即一串随机字符串)所分割出来的文件字节码中有两行特殊字符,即第一行内容文件头和一行空行。之后的第三行才是二进制的文件内容。
所以在服务端接受客户端上传的文件时,获取HTTP请求参数中的文件二进制时,要去掉前三行。

3.自己手工解析上传的txt文件:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 如果一个表单的类型是post且enctype为multipart/form-date
 * 则所有数据都是以二进制的方式向服务器上传递。
 * 所以req.getParameter("xxx")永远为null。
 * 只可以通过req.getInputStream()来获取数据,获取正文的数据
 * 
 * @author wangxi
 *
 */
public class UpServlet extends HttpServlet {
   
    public void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        String txt = req.getParameter("txt");//返回的是null
        System.err.println("txt is :"+txt);
        System.err.println("=========================================");
        InputStream in = req.getInputStream();
//      byte[] b= new byte[1024];
//      int len = 0;
//      while((len=in.read(b))!=-1){
   
//          String s = new String(b,0,len);
//          System.err.print(s);
//      }
        BufferedReader br = new BufferedReader(new InputStreamReader(in));
        String firstLine = br.readLine();//读取第一行,且第一行是分隔符号,即随机字符串(Content-Type中的boundary)
        String fileName = br.readLine();//第二行文件信息,从中截取出文件名
        fileName = fileName.substring(fileName.lastIndexOf("\\")+1);// xxxx.txt"
        fileName = fileName.substring(0,fileName.length()-1);

        br.readLine();  //boundary 分割流中的Content-Type,上传的文件类型
        br.readLine();  //空行
        String data = null;
        //获取当前项目的运行路径
        String projectPath = getServletContext().getRealPath("/up");
        PrintWriter out  = new PrintWriter(projectPath+"/"+fileName);
        while((data=br.readLine())!=null){
            if(data.equals(firstLine+"--")){
                break;
            }
            out.println(data);
        }
        out.close();
    }
}

如果是同时上传多个文件(form表单中有多个 file):
HTTP头信息:

POST /user/login/upload HTTP/1.1
Host: 127.0.0.1:8090
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Cache-Control: no-cache

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name=""; filename="xxx.numbers"
Content-Type: application/x-iwork-keynote-sffnumbers

...流
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name=""; filename="AdjacencyMatrix.js"
Content-Type: text/javascript

...流
------WebKitFormBoundary7MA4YWxkTrZu0gW--

4.使用apache-fileupload处理文件上传:
框架:是指将用户经常处理的业务进行一个代码封装。让用户可以方便的调用。
目前文件上传的(框架)组件:
Apache—-fileupload -
Orialiy – COS – 2008() -
Jsp-smart-upload – 200M。
用fileupload上传文件:
需要导入第三方包:

    Apache-fileupload.jar – 文件上传核心包。
    Apache-commons-io.jar – 这个包是fileupload的依赖包。同时又是一个工具包。

核心类:

    DiskFileItemFactory  设置磁盘空间,保存临时文件。只是一个具类。
    ServletFileUpload   文件上传的核心类,此类接收request,并解析reqeust。
    ServletfileUpload.parseRequest(requdest)  - List<FileItem>
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值