前言:

干了这几个项目,也做过几次文件上传下载,要么是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读取。

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

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

  1. Java文件上传的几种方式

    文件上传与文件上传一样重要.在Java中,要实现文件上传,可以有两种方式: 1.通过Servlet类上传 2.通过Struts框架实现上传 这两种方式的根本还是通过Servlet进行IO流的操作. 一 ...

  2. 小兔Java教程 - 三分钟学会Java文件上传

    今天群里正好有人问起了Java文件上传的事情,本来这是Java里面的知识点,而我目前最主要的精力还是放在了JS的部分.不过反正也不麻烦,我就专门开一贴来聊聊Java文件上传的基本实现方法吧. 话不多说 ...

  3. 2013第38周日Java文件上传下载收集思考

    2013第38周日Java文件上传&下载收集思考 感觉文件上传及下载操作很常用,之前简单搜集过一些东西,没有及时学习总结,现在基本没啥印象了,今天就再次学习下,记录下自己目前知识背景下对该类问 ...

  4. JAVA文件上传 ServletFileUpLoad 实例

    1.  jsp <%@ page language="java" contentType="text/html" pageEncoding="u ...

  5. curl文件上传有两种方式,一种是post_fileds,一种是infile

    curl文件上传有两种方式,一种是POSTFIELDS,一种是INFILE,POSTFIELDS传递@实际地址,INFILE传递文件流句柄! );curl_setopt($ch, CURLOPT_PO ...

  6. java文件上传工具包

    java 文件上传工具包 主要有两个方法:单文件上传和多文件上传 @Slf4j public class UploadFileUtil { //上传单张图片 public String uploadP ...

  7. Servlet中文件上传的几种方式

    上传文件,因为上传的都是二进制数据,所以在Servlet中就不能直接用request.getParameter();方法进行数据的获取,需要借助第三方jar包对上传的二进制文件进行解析.常用的方式如下 ...

  8. java文件上传方式1servlet 方式2springmvc

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletExcepti ...

  9. java文件上传和下载

    简介 文件上传和下载是java web中常见的操作,文件上传主要是将文件通过IO流传放到服务器的某一个特定的文件夹下,而文件下载则是与文件上传相反,将文件从服务器的特定的文件夹下的文件通过IO流下载到 ...

随机推荐

  1. centos6.5(64位)离线安装scalr

    1.下载scalr-server安装备包: 下载地址:http://pan.baidu.com/s/1eSA3dom scalr-server-5.1.0.oss-nightly.2015013004 ...

  2. Oracle实例名,服务名等概念区别与联系

    数据库名.实例名.数据库域名.全局数据库名.服务名 , 这是几个令很多初学者容易混淆的概念.相信很多初学者都与我一样被标题上这些个概念搞得一头雾水.我们现在就来把它们弄个明白. 一.数据库名 什么是数 ...

  3. dlib安装教程(for linux)

    https://blog.csdn.net/LoHiauFung/article/details/78454905 https://www.linuxidc.com/Linux/2017-11/148 ...

  4. python socket.error: [Errno 10061]

    用Python写server和client时候如果server中sock.bind(('localhost', 8001))  则client中sock.connect(('localhost', 8 ...

  5. HDU1078 FatMouse and Cheese(DFS+DP) 2016-07-24 14:05 70人阅读 评论(0) 收藏

    FatMouse and Cheese Problem Description FatMouse has stored some cheese in a city. The city can be c ...

  6. 一句话为当前窗口客户区捉图: GetFormImage 来自万一的博客

    一句话为当前窗口客户区捉图: GetFormImage http://www.cnblogs.com/del/archive/2008/10/24/1318738.html unit Unit1; i ...

  7. WPF 打印崩溃问题( 异常:Illegal characters in path/路径中有非法字符)

    现象: 打印时候程序直接崩溃.调试时出现下列异常. 异常信息: 中文:System.ArgumentException : 路径中有非法字符. 英文: System.ArgumentException ...

  8. 如何将Jenkins multiline string parameter的多行文本优雅的保存为文件

    [现象]: 使用multi-line string parameter获取的文本变量,在jenkins shell里面显示为单行文本(空格分割). [问题]:能否转换为多行文本,并存入文件. [解决方 ...

  9. jquery chosen 插件多选初始化

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  10. ASP.NET Core SignalR CORS 跨域问题

    将 SignalR 集成到 ASP.NET Core api 程序的时候,按照官方 DEMO 配置完成,本地访问没有问题,但是发布之后一直报跨域问题,本地是这样设置的: 原始代码: services. ...