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的方法来上传文 ...
随机推荐
- ionic 搜索双向数据绑定失效
1.用data对象存储变化的数据 js: $scope.data={}; $scope.data.keywords = ""; $scope.search = function() ...
- 最小高度的树 Minimum Height Trees
2018-09-24 12:01:38 问题描述: 问题求解: 毫无疑问的一条非常好的题目,采用的解法是逆向的BFS,也就是从叶子节点开始遍历,逐步向中心靠拢,最终留下的叶子节点就是答案. publi ...
- Ribbon
Ribbon是一个客户端的负载均衡器,它提供对大量的HTTP和TCP客户端的访问控制.Feign也是用的Ribbon,所以在这一章你也可以用@FeignClient Ribbon的一个核心概念是命名的 ...
- English trip M1 - AC1 My Dream Car Teacher:Corrine
In this lesson you will learn to describe an object. 课上内容(Lesson) You want to rent a car. Go to the ...
- 20181013xlVba导入成绩
Sub 导入成绩() Const TargetSheet = "年级_原始成绩汇总" Const DesSheet = "年级_本次成绩总表" Applicat ...
- 自定义session的存储机制
<?php class MSession implements SessionHandlerInterface{ // reids 对象 protected $handler = null; / ...
- 【洛谷p1319】压缩技术
(许久不见,甚是想念) 压缩技术[传送门] 洛谷上滴算法标签: 然而这是一道入门难度的题.(不管不管,就写它了) 好的先说一下思路吧wait!我忘记了咋做的当时. 首先做题第一道坎儿,如何输入若干个( ...
- hdu 1542 Atlantis (线段树扫描线)
大意: 求矩形面积并. 枚举$x$坐标, 线段树维护$[y_1,y_2]$内的边是否被覆盖, 线段树维护边时需要将每条边挂在左端点上. #include <iostream> #inclu ...
- NIM 博弈 牛客小白月赛2 E-是是非非
题目链接 分析:一个裸的NIM博弈 对于一个Nim游戏的局面(a1,a2,...,an),它是P-position(即当前局面先手必败)当且仅当a1^a2^...^an=0,其中^表示异或(xor)运 ...
- 第一阶段——站立会议总结DAY02
1.昨天做了什么:做出了一个大概的界面(APP的个人中心界面),有用户名信息和按钮. 2.今天准备做什么:因为仅是完成在页面上显示文字,而显示个人信息的化,想要做成微信的个人中心辣个样子. ①就是文字 ...