Java Web(十一) 文件上传与下载
文件上传
上传的准备工作
- 表单method必须为post
- 提供file组件
- 设置form标签的enctype属性为multipart/form-data,如果没有设置enctype属性,浏览器是无法将文件自身传递到服务端的(enctype默认为application/x-www-form-urlencoded)
<form action="fileupload.do" method="post" enctype="multipart/form-data">
用户名:<input type="text" name="username"/><br/>
密码:<input type="password" name="password"/><br/>
上传文件:<input name="file" type="file" /><br/>
<input type="submit"/>
</form>
上传时HTTP协议的格式
enctype为application/x-www-form-urlencoded时
从表单发送数据到服务器,数据是以键值对的形式存放在请求体中发送到服务器的。
使用google浏览器的自动抓包(F12),可以查看表单数据在HTTP协议中的格式:

request.getParameter(name)是以键值对的形式获取值的,所以可以通过该方法得到表单中的数据。可以得到文件名,但是得不到文件!
enctype为multipart/form-data时
在上传时,multipart/form-data请求会把表单的数据处理为一条消息,以标签为单元,用分隔符(boundary)分开。既可以上传普通表单数据,也可以上传文件。content-disposition,用来说明字段的一些信息。当上传的字段是文件时,会有Content-Type来表明文件类型。
使用google浏览器查看上传时表单数据在HTTP协议的格式:

表单数据在HTTP协议中不是以键值对形式存在的,所以在服务器端是无法通过request.getParameter(name)获取数据的。
可以利用分隔符boundary和Content-type属性自己编写代码实现文件上传。
在服务器端查看从客户端传来的表单数据
可以使用request.getInputStream()来获取从客户端传来的数据,可以通过下面的代码把传来的数据输出到控制台:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
InputStream is = request.getInputStream();
int i = is.read();
while(i != -1) {
char c = (char)i;
System.out.print(c);
i = is.read();
}
}
在没有设置enctype属性时,传到服务器的数据为:

文件上传时,传到服务器的数据为:

其中的乱码为二进制数据,也就是要上传的文件。
FileUpload实现文件上传
FileUpload 是 Apache commons下面的一个子项目,用来实现Java环境下面的文件上传功能。
使用FileUpload需要两个jar包的支持,这里FileUpload版本为:commons- fileupload-1.2.1,Commons IO版本为:commons-io-1.4。
客户端代码:
<body>
<form action="fileupload.do" method="post" enctype="multipart/form-data">
用户名:<input type="text" name="username"/><br/>
密码:<input type="password" name="password"/><br/>
上传文件:<input name="file" type="file" /><br/>
<input type="submit"/>
</form>
</body>
服务器端代码为:
@WebServlet(name = "FileServlet",urlPatterns = "/fileupload.do")
public class FileServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//判断是否支持文件上传
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if(!isMultipart) {
throw new RuntimeException("不支持文件上传");
}
//创建一个磁盘工厂
DiskFileItemFactory factory=new DiskFileItemFactory();
//配置缓存库
ServletContext servletContext = this.getServletConfig().getServletContext();
File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
factory.setRepository(repository);
//解析数据
ServletFileUpload fileUpload=new ServletFileUpload(factory);
List<FileItem> items = null;
try {
items=fileUpload.parseRequest(request);
} catch (FileUploadException e) {
e.printStackTrace();
}
for(FileItem item : items) {
if (item.isFormField()) {
String name = item.getFieldName();
String value = item.getString();
System.out.println(name + " " + value);
} else {
//取文件名
String fileName = item.getName();
fileName = fileName.substring(fileName.lastIndexOf("\\") + 1);
//取文件拓展名
String exten = fileName.substring(fileName.lastIndexOf("."));
//新文件名,防止文件重名
String newFileName = UUID.randomUUID().toString().replace("-", "") + exten;
//把文件写入到upload文件夹下
String path = this.getServletConfig().getServletContext().getRealPath("/");
String directPath = path + "upload\\" + newFileName;
File file = new File(directPath);
OutputStream os = new FileOutputStream(file);
InputStream is = item.getInputStream();
byte[] b = new byte[1024];
int len = 0;
while ((len = is.read(b)) != -1) {
os.write(b, 0, len);
}
os.close();
is.close();
}
}
request.getRequestDispatcher("ok.jsp").forward(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
文件下载
@WebServlet(name = "DownloadServlet", urlPatterns = "/download.do")
public class DownloadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 获得要下载的文件的名称
String filename = request.getParameter("filename");
// 告诉客户端该文件不是直接解析,而是以附件形式打开(下载)
response.setHeader("Content-Disposition", "attachment;filename=" + filename);
// 获取文件的绝对路径
String path = this.getServletContext().getRealPath("download/" + filename);
// 获得该文件的输入流
InputStream in = new FileInputStream(path);
// 获得输出流--通过response获得的输出流 用于向客户端写内容
ServletOutputStream out = response.getOutputStream();
// 文件拷贝代码
int len = 0;
byte[] buffer = new byte[1024];
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
in.close();
out.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
Java Web(十一) 文件上传与下载的更多相关文章
- java web(四)文件上传与下载
一.文件上传原理 1.在TCP/IP中,最早出现的文件上传机制是FTP ,它是将文件由客户端发送到服务器的标准机制:但是在jsp使用过程中不能使用FTP方法上传文件,这是由jsp运行机制所决定. 通 ...
- java+web+大文件上传下载
文件上传是最古老的互联网操作之一,20多年来几乎没有怎么变化,还是操作麻烦.缺乏交互.用户体验差. 一.前端代码 英国程序员Remy Sharp总结了这些新的接口 ,本文在他的基础之上,讨论在前端采用 ...
- 【Java】JavaWeb文件上传和下载
文件上传和下载在web应用中非常普遍,要在jsp环境中实现文件上传功能是非常容易的,因为网上有许多用java开发的文件上传组件,本文以commons-fileupload组件为例,为jsp应用添加文件 ...
- java实现大文件上传和下载
[文件上传和下载]是很多系统必备功能, 比如PM\OA\ERP等:系统中常见的开发模式有B/S和C/S,而前者主要是通过浏览器来访问web服务器,一般采用七层协议中的[应用层http]进行数据传输,后 ...
- Java实现FTP文件上传与下载
实现FTP文件上传与下载可以通过以下两种种方式实现(不知道还有没有其他方式),分别为:1.通过JDK自带的API实现:2.通过Apache提供的API是实现. 第一种方式 package com.cl ...
- java+web+多级文件上传
文件夹数据库处理逻辑 publicclass DbFolder { JSONObject root; public DbFolder() { this.root = new JSONObject(); ...
- java web关于文件上传下载的总结
文件上传使用<form method="POST" enctype="multipart/form-data"> , 而不是默认的applica ...
- java支持断点续传文件上传和下载组件
java两台服务器之间,大文件上传(续传),采用了Socket通信机制以及JavaIO流两个技术点,具体思路如下: 实现思路: 1.服:利用ServerSocket搭建服务器,开启相应端口,进行长连接 ...
- Java中的文件上传和下载
文件上传原理: 早期的文件上传机制: 在TCP/IP中.最早出现的文件上传机制是FTP.他是将文件由客户端发送到服务器的标准机制. jsp中的文件上传机制: 在jsp编程中不能使用FTP的方法来上传文 ...
随机推荐
- vim的简单使用
vim的学习曲线相当的大(参看各种文本编辑器的学习曲线),所以,如果你一开始看到的是一大堆VIM的命令分类,你一定会对这个编辑器失去兴趣的.下面的文章翻译自<Learn Vim Progress ...
- [转][osg][QT]osg与QT界面结合的简单例子
//QT += core gui opengl //LIBS += -losgViewer -losgDB -losgUtil -losg -lOpenThreads -losgGA -losgQt ...
- php 建站 多域名配置 自定义重定向
1. 申请一个域名 , 当多个域名使用. 比如 申请一个顶级域名为 .com 后缀的一级域名 :mine.com, 一般允许绑定四五个二级域名,比如 www.mine.com . mine.mine ...
- d3 + geojson in node
d3.js本来主要是用于用“数据驱动dom”,在浏览器端,接收后端数据,数据绑定,渲染出svg. 即使是在ng中用,也是会由框架打包,供客户端下载. 那么,如果用所谓后端渲染,发布静态的svg,那就要 ...
- css3动画实现伪弹幕效果
如图所示: 效果还可以直接用麦唱APP把一首歌分享到微信里面看到,方法类似全民K歌的方法,都是用css3动画实现的, 代码如下:(这是我做真实效果前的一个dome) 直接粘代码就可以看到效果,里面有两 ...
- Python全栈开发-Day8-Socket网络编程
本节内容 断言 Socket构建框架 ftp构建框架 Socket粘包 Socket介绍 Socket参数介绍 基本Socket实例 通过Socket实现简单SSH SocketServer 支持多用 ...
- Java从内存流中读取byte数组
Java中通过servlet接收二进制数据,然后将二进制数据流读取为byte数组.开始使用:byte[] bs = new byte[request.getContentLength()];reque ...
- python中的面向对象学习以及类的封装(这篇文章初学者一定要好好看)
这篇文章对于初学者可以很有效的理解面对过程.面对对象 一.首先介绍一下面向过程和面向对象的比较: 面向过程 VS 面向对象 编程范式 编程是程序员用特定的语法+数据结构+算法组成的代码来告诉计算机如何 ...
- office2016如何激活
office2016如何激活 一.总结 一句话总结:office2016没有激活成功,下了一个office2013破解版 office2013破解版 二.自己做法 三中的方法点赞蛮多的(100多个), ...
- bedtools神器 | gtf转bed | bed文件运算
我们生信技能书有一篇介绍bedtools的文章,可以在微信里搜着看下,非常有用. http://bedtools.readthedocs.io/en/latest/ gtf转bed用Linux命令完全 ...