java文件上传-原始的Servlet方式

lihaoyang 2021-08-29 原文


java文件上传-原始的Servlet方式

前言:

干了这几个项目,也做过几次文件上传下载,要么是copy项目以前的代码,要么是百度的,虽然做出来了,但学习一下原理弄透彻还是很有必要的。刚出去转了一圈看周围有没有租房的,在北京出去找房子是心里感觉最不爽的时候,没有归属感,房租还不便宜,RT,不能好高骛远,还是脚踏实地一点一点学技术吧,终将有一日,工资会涨的。

java文件上传

传统的文件上传,不用jquery插件的话,就是用form表单提交,项目里用过uploadify,可以异步上传文件,原理我也没研究。现在说传统的form表单上传文件。

文件上传核心:

  1. 用<input type=”file”/> 来声明一个文件域。样式如  文件:_____ <浏览>.
  2. 必须使用post方式提交表单。
  3. 必须设置表单的类型为multipart/form-data.是设置这个表单传递的不是key=value值。传递的是字节码.

新建web项目:

jsp form表单:enctype(编码类型)的默认值就是 application/x-www-form-urlencoded

 

浏览器查看 http报文:

主要参数:

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8    接收服务器返回的类型,*/*表示所有。

Referer:http://localhost:8888/upload/    来自哪个网站

Accept-Language:zh-CN,zh;q=0.8 :请求回应中首选的语言为简体中文

Accept-Encoding:gzip, deflate, br支持的压缩格式

User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36   用户浏览器类型

Host:localhost:8888 主机地址

Connection:keep-alive 报文发送完毕后仍然保持连接

Cache-Control: max-age=0  缓存

Content-Length: 41 41字节

对文件上传来说,重要的参数是:

Content-Type: application/x-www-form-urlencoded

这个参数只有post请求才有,默认就是application/x-www-from-urlencoded ,Content-type表示正文类型,get方式没有正文,因为参数在url里。

在Servlet里可以用request对象取到Content-type:request.getHeader(“Content-type”); 默认的值为 application/x-www-form-urlencoded,

如果是get请求,则 request.getHeader(“Content-type”);为null。

下图是get请求时的http头信息,参数再url传递,没有Content-type

 

 

 


文件上传,必须设置enctype=”multipart/form-data”

from表单:

上传一个word:

此时的http消息的Content-Type:

其中的 boundary=—-WebKitFormBoundary44gVxAkoSg3tk3oR 指的是文件上传的分隔符。在请求正文里体现。

看请求的正文:

—–xxxxxxxxxx 标识文件开始,最后一行的 ——–xxxxxxxxxxxx–(分隔符末尾多了2个–),标识文件结束。第一个input 是text类型,第二个是二进制,content-type 是application/octet-stream 表示 二进制流。如果选择的是图片,Content-Type: image/jpeg,文本则,Content-Type: text/plain。

 

 

二进制流的接收:

当表单类型是post类型,切enctype=”multipart/form-data”,则所有的数据都是以二进制流的形式向服务器上传,所以request.getParameter(“xxx”) 永远为null,只能通过req.getInputStream(); 获取正文。

上传一个txt:

Servlet:

package com.lhy.upload;

import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 
 * @author Administrator
 *
 */
@WebServlet(name="UploadServlet",urlPatterns="/UploadServlet")
public class UploadServlet extends HttpServlet{

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
//        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        
        req.setCharacterEncoding("UTF-8");
        String contentType = req.getHeader("Content-type");
        System.out.println("contentType:  "+contentType);
        String name = req.getParameter("name");
        System.out.println(name);//null
        
        InputStream is = req.getInputStream();
        
        
//        ------WebKitFormBoundaryG0ULv7eVfQ1K2PBA
//        Content-Disposition: form-data; name="image"; filename="静夜思.txt"
//        Content-Type: text/plain
//
//
//        ------WebKitFormBoundaryG0ULv7eVfQ1K2PBA--
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String firstLine = br.readLine();//第一行,分隔符
        String fileName = br.readLine();
//        Content-Disposition: form-data; name="image"; filename="jingyesi.txt"
        fileName = fileName.substring(fileName.lastIndexOf("=")+2,fileName.length()-1);
        
        br.readLine();
        br.readLine();
        String data = null;
        //获取当前项目的运行路径
        String path = getServletContext().getRealPath("/up");
        PrintWriter pw = new PrintWriter(path+"/"+fileName);
        while((data = br.readLine()) != null){
            if(data.equals(firstLine+"--")){
                break ; //读到了文件尾
            }
            pw.println(data);
        }
        pw.flush();
        pw.close();
        is.close();

        
       /* FileOutputStream  fos = new FileOutputStream(path+"/"+"b.doc");
//        byte[] b = new byte[1024];
        int len = 0;
        while((len = is.read()) != -1){
            fos.write(len);
        }
        fos.flush();
        fos.close();
        is.close();*/
    }

    
}

项目里:

例子只是读取了txt,其他的二进制需要使用inputStream读取。

我读取了图片写到项目里,打不开,大小比原始图片会小一点,不知为何

 

欢迎关注个人公众号一起交流学习:

发表于
2017-08-06 12:59 
我俩绝配 
阅读(899
评论(0
编辑 
收藏 
举报

 

版权声明:本文为lihaoyang原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/lihaoyang/p/7291175.html

java文件上传-原始的Servlet方式的更多相关文章

随机推荐

  1. 下载旧版chrome

    下载旧版chrome 问题描述: xp只能使用chrome 49及其之前的版本,去哪里下载?   解决办法: […]...

  2. 通用数字中文互转换工具代码

    今天在CodeProject首次发表文章:http://www.codeproject.com/KB/cs/N […]...

  3. MCU 51-1概述 – Darren_pty

    MCU 51-1概述 Microcontroller Unit  单片机:将微处理器CPU、存储器(RAM、R […]...

  4. 新支付宝微信及个人免签支付系统中-短信信息自动回调源码监测APP 实时自动回调对接集成!

    新支付宝微信及个人免签支付系统中-短信信息自动回调源码监测APP 实时自动回调对接集成! 1.使用设置方法:回 […]...

  5. ip通信回顾

    每个层的结构: 接入层     星型网 汇聚层     树型网 核心层     分布式网络   数据传输方式分 […]...

  6. 听云数据库管理平台NetopGO简介

    ➠更多技术干货请戳:听云博客 断断续续写了将近一个月,听云第一版数据库管理平台终于写完了,期间来来回回的改了好 […]...

  7. Python 爬虫从入门到进阶之路(十二)

    之前的文章我们介绍了 re 模块和 lxml 模块来做爬虫,本章我们再来看一个 bs4 模块来做爬虫。 和 l […]...

  8. .NET Core之单元测试(三):Mock框架Moq的使用

    编写一个API 新增一个接口 public interface IFoo { bool Ping(string […]...

展开目录

目录导航