HTTP Post 文件的一些细节

JSP/SERVLET上载的难点
  1、支持任意格式、任意数量的文件上载;2、上载控制的实现;3、表单信息的取得;4、“即插即用”的应用方法;我个人认为,制约通用 上载组件的实现主要是这四个难点。
  
   JSP/SERVLET上传的原理
   JSP/SERVLET文件 上载是通过ServletInputStream类来实现的,ServletInputStream类是java.io.InputStream的一个扩 展抽象类,实质上也是一个输入流,通过ReadLine方法从Request端一行一行读取,可见,JSP/SERVLET上载根本上是用流来实现的,理 解了这个就不难理解整个 上载的原理。ServletInputStream实现文件 上载必须采用HTTP POST或者HTTP PUT协议,HTTP GET协议只能传递很少的

数据 ,是不能实现文件上载的。
   
  下面我们来看一下上传的数据流的结构,首先要在BROWSER端给出一个请求,我们的请求如下(文件名为test1.jsp):
  <%@ page contentType="text/html; charset=GBK" %>
  <html>
  <head>
  
  <title>文件上载</title>
  </head>
  <body>
  <form action="test2.jsp" enctype="MULTIPART/FORM-DATA" method=post>
  说明一: <input type="text" name="explain1" />
  <br />
  说明二: <input type="text" name="explain2" />
  <br />
  请选择上载文件1 <input type="file" name="file1" />
  <br />
  请选择上载文件2 <input type="file" name="file2" />
  <br />
  说明三: <input type="text" name="explain3" />
  <br />
  <input type="submit" value=" 上 载 " />
  </form>
  </body>
  </html> 
  显示如下:
   
  说明一:
  
  说明二:
   
  请选择上载文件一:
   
  请选择上载文件二:
   
  说明三:
   
  在上载请求页中混杂了表单的三个输入框,及两个上载文件,当然输入框可以更多、更杂,可以有选择框、单选及多选按钮,待上传的文件也可以有三个、四个或所需要的更多。
   
   action="test2.jsp"表示表单将提交到"test2.jsp",另外注意表单属性中必须要有这 句:enctype="MULTIPART/FORM-DATA",enctype指定 Form 输入资料的编码方式,“method”属性必须为“post”,这样表单才能提交大量数据,也表示本表单的数据传递将用流操作,“method=get” 表示数据将通过地址栏进行传递,虽然方便快捷,但只适合很少的数据量。
   
  响应端“test2.jsp”页面如下:
   
  <%@ page contentType="text/html; charset=GBK" %>
  <html>
  <head>
  <title>文件上载</title>
  </head>
  <body>
  <jsp:useBean id="upBean" scope="page" class="com.upload.UpBean"/>
  <%
  upBean.doUpload(request);
  out.println("上载已完成,请查看输出文件");
  %>
  </body>
  </html> 
  
   test2.jsp收到请求后,调用一个java bean执行doUpload(request)操作,本操作将完成流(unicode格式)的接收并不做任何处理地将流顺序写入一个文本文件里,读写操 作中用了一个缓冲区byte[] readByte,用了一个ServletInputStream 的一个方法readLine(byte[] b, int off,int len)方法读取流,请大家注意,ServletInputStream 流的read Line方法是一次读入指定大小的行,java bean (UpBean.java)代码如下:
   
  [code]package com.upload;
  
  import java.io.*;
  import javax.servlet.*;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.ServletInputStream;
   
  public class UpBean {
   
  public void doUpload(HttpServletRequest req) throws ServletException, IOExcept
  ion{
  //首先定义一个文本文件
  File file = new File("out.txt");
  //readCount 记录从输入流中实际读取的字符数
  int readCount;
  //输入流缓冲区
  byte[] readByte = new byte[1024];
  //初始化输入流
  ServletInputStream servletInputStream = req.getInputStream();
  //初始化一个输出流(到文件)
  FileOutputStream fileOutputStream = new FileOutputStream(file);
  //循环从读取输入流中读取字节
  readCount = servletInputStream.readLine(readByte, 0,readByte.length);
  
  while(readCount != -1){
  fileOutputStream.write(readByte,0,readCount);
  readCount = servletInputStream.readLine(readByte, 0, 1024);
  }
  //关闭文件流
  fileOutputStream.flush();
  }
  }[/code] 
   
  为了便于我们阅读流,上载的两个文件为两个 简单 的文本文件(有格式的文件,不便于直接分析):one.txt及two.txt,文件内容如下,实验时请建立对应文本文件,内容请直接copy以下所示:
   
  one.txt:
   
  one
  one one
  one one one
   
     two.txt
  two
  two two
  two two two
   
  都准备好以后,我们就可以运行了,运行时请注意,文本部分及文件部分最好不要出现汉字,或其他双字符集字符,尽量采用英文,因为接收是采用的Unicode字符集,我们未对输入做任何处理。 我们在三个输入框输入的字符为,说明一:explain1;说明二:explain2;说明三:explain3,out.txt接收到如下字符:
   
  -----------------------------7d2623a3e0286
  Content-Disposition: form-data; name="explain1"
   
  explain1
  -----------------------------7d2623a3e0286
  Content-Disposition: form-data; name="explain2"
   
  explain2
  -----------------------------7d2623a3e0286
  Content-Disposition: form-data; name="file1"; filename="C:/test/one.txt"
  Content-Type: text/plain
   
  one
  
  one one
  one one one
  -----------------------------7d2623a3e0286
  Content-Disposition: form-data; name="file2"; filename="C:/test/two.txt"
  Content-Type: text/plain
   
  two
  two two
  two two two
  -----------------------------7d2623a3e0286
  Content-Disposition: form-data; name="explain3"
   
  explain3
  -----------------------------7d2623a3e0286--
   可以很明显的看到,out.txt被“-----------------------------7d2623a3e0286”分成了五 节,即表单的每个输入部分都对应一节,结尾部分是“-----------------------------7d2623a3e0286--”,刚好 比开始的一段字符在最后多出两个“-”, 每节的第一行是输入内容的说明“Content-Disposition: form-data”,“name="explain1"”表示 上载请求项的name,文本输入部分仅这两个说明,如果输入的是文件还用两项说明:“filename="C:/test/one.txt"”,表示输入 源,基于ms-windows的ie上载带有完整的路径,netscape及其他浏览器可能只有一个文件名;还有一项是关于输入格式的“Content- Type:text/plain”;表示输入格式是文本类型,如果我们上载的是bmp文件则为“Content-Type: image/bmp”,word文件为“application/msword”...,说明的下面紧接着是一个空行,然后下面才是我们所需的内容。
   
  仔细分析未加修改的输入流格式,有助于我们实现文件与输入文本的准确分离。
   通过以上的分析可以看出,准确分离上载的文件及文本信息需要以下要素:1、数据段分割符、结束符(比分割符多出两个“-”);2、输入文本及上载的文件 区分标志(文本为“name=”,文件为“filename=”);3、编码格式,可以通过HttpServletRequest 类getCharacterEncoding() 方法取得。4、表单文本部分名称及内容,名称为“name=”后面的字符,内容为该段第三行及以后的内容;5、文件名称及内容,名称为 “filename=”后面的字符,内容为该段第三行及以后的内容。
   
  下面我们将讨论输入流的分离。
   
  程序实现分析
   我们首先画出程序实现的主体结构图,请注意判断文件标志(indexOf("filename=")>0),与判断文本标志 (indexOf("name=")>0)的顺序,当(indexOf("filename=")>0)成立时, (indexOf("name=")>0)一定也是成立的,所以判断文件要在判断文本前。
   
  分离文件及输入文本,为完整

保存 上 载的文件信息及输入的文本信息,本程序建立了两个类:public class FileInfo 、public class InputField,及两个线性表private ArrayList upFilesList、private ArrayList inputFieldList,用于动态增加文件信息及文本信息,定义如下:
   
  FileInfo.java(记录上载文件信息)
   
  package com.upload;
   
  public class FileInfo {
  private String fileName;
  private boolean validFlag;
  private String filePath;
  private long fileSize;
   
  //设置文件信息
  //上载文件是否有效标志
  public void setValidFlag(boolean validFlag){
  
  this.validFlag = validFlag;
  }
  //文件名
  public void setFileName(String filename){
  this.fileName = filename;
  }

HTTP post 上传相关推荐

  1. 本地打包Docker镜像上传至阿里云远程仓库(一站式脚本)

    打包镜像上传至远程仓库: 1. 本地项目为 mytest-project 2. 仓库为阿里云镜像仓库 registry.cn-beijing.aliyuncs.com/test/mytest-proj ...

  2. springboot设置文件上传大小(tomcat默认1M)

    application.yml # 设置文件上传大小(tomcat默认1M) server:tomcat:max-http-form-post-size: -1 spring:servlet:mult ...

  3. 将文件上传至ftp服务器,FTP文件上传工具类,将文件上传至服务器指定目录

    将文件上传至ftp服务器,传入File对象,将文件上传至ftp服务器 需要配置修改的点: 1. 服务器ip端口(服务器ip 端口22/21). 2. 服务器账号密码(服务器登录用户名密码). 3. 上 ...

  4. canvas java 上传截图_在Vue项目中使用html2canvas生成页面截图并上传

    使用方法 项目中引入 npm install html2canvas html代码 //html代码 js代码 // 引入html2canvas import html2canvas from 'ht ...

  5. Springboot 多文件上传

    其实多个文件和单个文件上传是一样的,可以使用同一个Controller 添加依赖 <!-- https://mvnrepository.com/artifact/commons-fileuplo ...

  6. pycharm连接远程服务器并进行代码上传+远程调试

    Pycharm连接远程服务器并进行代码上传+远程调试 </h1><div class="clear"></div><div class=& ...

  7. Springboot前后端分离上传、下载压缩包、查看文件

    Controller层: /*** 保存附件按钮* @param file 附件* @return 附件路径**/@PostMapping(value = "/upload")Ob ...

  8. github自己的仓库给别人上传代码的操作

    点击自己工程上面的Setting 接着点击 Collaborators 中间会有一个登陆操作 输入对面的账号 点击Add collaborator , 最后也就是最关键的一步就是 复制链接给对方,让他 ...

  9. 怎样往csdn上传自己的demo

    经常看到别的博客上有源码下载几个字,点击就能跳转界面 然后就是下载,如果刚接触博客,可能不知道是怎么回事呢 下面我截取图片演示操作的步骤 第一步: 第二步: 上传之后复制下地址 第三步: 那就是使用了 ...

  10. smartupload 上传文件时 把页面编码改成gbk 解决乱码

    快来java1234 吧 smartupload 上传文件时,经常会发生因为把表单设置为 enctype="multipart/form-data"而出现的中文乱码问题,本人头疼好 ...

最新文章

  1. go语言笔记——调试还很弱,用gdb来做?可用panic和defer。格式化代码使用gofmt,貌似我的vim插件是自带...
  2. boost::mp11::mp_drop相关用法的测试程序
  3. IOS设计模式之二(门面模式,装饰器模式)
  4. ehcache使用_Java 程序员如何使用 Shiro 框架
  5. Win7如何关闭 打开文件-安全警告
  6. linux oops产生原理,kernel panic , Oops 等cpu异常的分析与定位
  7. c++向量和数组的区别_Matlab入门基础知识(5)对数组的操作
  8. 机器视觉——棱镜的妙用
  9. MacOS Monterey12.3和Big Sur11.6.5离线安装包
  10. “Hello World!“”团队第七周召开的第二次会议
  11. chrome 历史版本下载
  12. Qt之切换语言的方法(传统数组法与Qt语言家)
  13. 全球及中国石油天然气开采行业产量情况及十四五开发战略规划报告2021年版
  14. 人工智能的味道 - 图像风格迁移 by Python
  15. 各种音视频编解码学习详解 h264 ,mpeg4 ,aac 等所有音视频格式
  16. Win10卸载office出现安装包语言不受系统支持
  17. thinkphp如何调试,打印错误信息sql等
  18. 第一章:一年365天,每天进步1‰,累计进步多少?一年365天,每天退步1‰,累计退步多少?format入门
  19. FSSC22000认证咨询,本程序适用与食品安全体系中的产品危害信息收集、分析和评估等所有活动
  20. python提示IndentationError: unexpected indent错误

热门文章

  1. JAVA微信开发(四), 公众号普通红包
  2. 【一起入门MachineLearning】中科院机器学习-期末题库-【计算题5+单选题19,20+简答题21】
  3. 矩阵相似,矩阵合同,矩阵等价概念总结
  4. AngularJs ng-options
  5. VLDB 2023 | 北大河图发布分布式训练神器Galvatron, 一键实现大模型高效自动并行...
  6. 生产制造|销售管理实时在线,业务效率直线提升
  7. flume avro java_Flume的Avro Sink和Avro Source研究之一: Avro Source
  8. 李永乐复习全书线性代数 第四章 线性方程组
  9. 工作中的生长与完善——Leo鉴书86
  10. vue.js将秒转为天,小时,分钟秒的格式