文件上传

上传的准备工作

  • 表单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协议的格式

  1. enctype为application/x-www-form-urlencoded时

    从表单发送数据到服务器,数据是以键值对的形式存放在请求体中发送到服务器的。

    使用google浏览器的自动抓包(F12),可以查看表单数据在HTTP协议中的格式:

    request.getParameter(name)是以键值对的形式获取值的,所以可以通过该方法得到表单中的数据。可以得到文件名,但是得不到文件!

  2. enctype为multipart/form-data时

    在上传时,multipart/form-data请求会把表单的数据处理为一条消息,以标签为单元,用分隔符(boundary)分开。既可以上传普通表单数据,也可以上传文件。content-disposition,用来说明字段的一些信息。当上传的字段是文件时,会有Content-Type来表明文件类型。

    使用google浏览器查看上传时表单数据在HTTP协议的格式:

    表单数据在HTTP协议中不是以键值对形式存在的,所以在服务器端是无法通过request.getParameter(name)获取数据的。

    可以利用分隔符boundary和Content-type属性自己编写代码实现文件上传。

  3. 在服务器端查看从客户端传来的表单数据

    可以使用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(十一) 文件上传与下载的更多相关文章

  1. java web(四)文件上传与下载

     一.文件上传原理 1.在TCP/IP中,最早出现的文件上传机制是FTP ,它是将文件由客户端发送到服务器的标准机制:但是在jsp使用过程中不能使用FTP方法上传文件,这是由jsp运行机制所决定. 通 ...

  2. java+web+大文件上传下载

    文件上传是最古老的互联网操作之一,20多年来几乎没有怎么变化,还是操作麻烦.缺乏交互.用户体验差. 一.前端代码 英国程序员Remy Sharp总结了这些新的接口 ,本文在他的基础之上,讨论在前端采用 ...

  3. 【Java】JavaWeb文件上传和下载

    文件上传和下载在web应用中非常普遍,要在jsp环境中实现文件上传功能是非常容易的,因为网上有许多用java开发的文件上传组件,本文以commons-fileupload组件为例,为jsp应用添加文件 ...

  4. java实现大文件上传和下载

    [文件上传和下载]是很多系统必备功能, 比如PM\OA\ERP等:系统中常见的开发模式有B/S和C/S,而前者主要是通过浏览器来访问web服务器,一般采用七层协议中的[应用层http]进行数据传输,后 ...

  5. Java实现FTP文件上传与下载

    实现FTP文件上传与下载可以通过以下两种种方式实现(不知道还有没有其他方式),分别为:1.通过JDK自带的API实现:2.通过Apache提供的API是实现. 第一种方式 package com.cl ...

  6. java+web+多级文件上传

    文件夹数据库处理逻辑 publicclass DbFolder { JSONObject root; public DbFolder() { this.root = new JSONObject(); ...

  7. java web关于文件上传下载的总结

    文件上传使用<form method="POST"   enctype="multipart/form-data"> , 而不是默认的applica ...

  8. java支持断点续传文件上传和下载组件

    java两台服务器之间,大文件上传(续传),采用了Socket通信机制以及JavaIO流两个技术点,具体思路如下: 实现思路: 1.服:利用ServerSocket搭建服务器,开启相应端口,进行长连接 ...

  9. Java中的文件上传和下载

    文件上传原理: 早期的文件上传机制: 在TCP/IP中.最早出现的文件上传机制是FTP.他是将文件由客户端发送到服务器的标准机制. jsp中的文件上传机制: 在jsp编程中不能使用FTP的方法来上传文 ...

随机推荐

  1. file_put_contents结合print_r,打造日志功能

    <?php $log = []; $log['name'] = '张三'; $log['age'] = '15'; $log['date'] = date('Y-m-d'); echo prin ...

  2. 学大数据是先学java还是先学python?

    大数据的发展趋势日渐明显,但是进入这个领域的门槛不小,除了要有心理准备,其次就是要付诸实际行动中去学习. 学习方法有很多,在没有基础的前提下,自学是因人而异是有难度.其次是大数据目前的工作方向主要是三 ...

  3. 关于video.js不错的一篇博客,

    博客地址: http://www.cnblogs.com/webenh/p/5815741.html

  4. C# : 泛型的继承关系实现的一个可以存放不同数据类型的链表

    以下定义的是一个链表结点类型: internal sealed class Node<T> { public T m_data; public Node<T> m_next; ...

  5. change color3

    两种方法 第一种 DataGridview1.Rows[i].DefultCellStyle.backcolor 第二种 AlternatingRowsDefutCellstyle 属性 获取或设置应 ...

  6. 管家基因 | Human housekeeping genes

    管家基因就是在细胞里稳定表达的基因,及时在胁迫状态下,表达的差异也不大. 以前做实验的时候就经常听说管家基因,因为在做RT-PCR的时候需要同时检测管家基因,这样可以用于矫正我们不同批次的结果. Li ...

  7. Vue.js示例:GitHub提交(watch数据,created钩子,filters过滤); 网格组件(功能:1.检索,2排序);

    GitHub提交 codePen:   https://codepen.io/chentianwei411/pen/wEVPZo 注意:频繁看案例,可能会被限制. 重点: 表单输入绑定, 单选按钮的使 ...

  8. 微信小程序发起微信支付

    点击链接查看详情:(支付中配置参数需要从后台得到->签名需要从微信申请才可以得到) https://mp.weixin.qq.com/debug/wxadoc/dev/api/api-pay.h ...

  9. Android VideoView播放网络视频简介(转)

    最近项目中用到了很多视频播放的地方,不管是聊天发送的视频消息,还是类似内涵段子的视频列表,都会涉及这些知识,不过网上的知识都很零散,一会找缓存方法,一会找预览图片的方法,一会找视频动态修改尺寸的方法, ...

  10. iptables -F 与 -X 区别

    test: 1.iptables 初始化 2.iptables -X (第一次) 错误原因是自定义链表(test)不为空 3.iptables -F 4.iptables -X ok,实验结束 实验报 ...