文件上传

上传的准备工作

  • 表单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. VC.时间_ZC测试代码

    1. #include <windows.h> #include <stdio.h> void TimeNowZ( char* _pc ) { SYSTEMTIME sys; ...

  2. 在选择列表中无效,因为该列既不包含在聚合函数中,也不包含在 GROUP BY 子句

    在选择列表中无效,因为该列既不包含在聚合函数中,也不包含在 GROUP BY 子句  突然看到这个问题,脑袋一蒙,不知道啥意思,后来想想,试图把select里的选项放到后面,问题自然解决!   下面这 ...

  3. JS异步函数 返回值

    1.  js 异步的几种情况 : 1.1 异步操作由浏览器内核的 webcore 来执行: onclick 由浏览器内核的 DOM Binding 模块来处理,当事件触发的时候,回调函数会立即添加到任 ...

  4. chkconfig命令参数

    chkconfig命令主要用来更新(启动或停止)和查询系统服务的运行级信息.谨记chkconfig不是立即自动禁止或激活一个服务,它只是简单的改变了符号连接. 使用语法:chkconfig [--ad ...

  5. 开发自己的R包(转)

    R不必说,数据统计分析可视化的必备语言,R包开发的门槛比较低,所以现在随便一篇文章都会发表一个自己的R包,这样有好处(各种需求早有人帮你解决了)也有坏处(R包太多,混乱,新手上手较难).作为生信工程师 ...

  6. 20165327 2017-2018-2 《Java程序设计》第9周学习总结

    20165327 2017-2018-2 <Java程序设计>第9周学习总结 教材内容总结 第十三章 (一)教材学习内容总结 理解 URL类是对统一资源定位符的抽象,使用URL创建对象的应 ...

  7. python try 异常处理 史上最全

    在程序出现bug时一般不会将错误信息显示给用户,而是现实一个提示的页面,通俗来说就是不让用户看见大黄页!!! 有时候我们写程序的时候,会出现一些错误或异常,导致程序终止. 为了处理异常,我们使用try ...

  8. 大div中嵌套小div,点击大div时隐藏,点击小div不隐藏

    给小div添加一个click事件 <div onClick="event.cancelBubble = true">  //小div

  9. 148. Sort List (java 给单链表排序)

    题目:Sort a linked list in O(n log n) time using constant space complexity. 分析:给单链表排序,要求时间复杂度是O(nlogn) ...

  10. BZOJ 1833 数字计数 数位DP

    题目链接 做的第一道数位DP题,听说是最基础的模板题,但还是花了好长时间才写出来..... 想深入了解下数位DP的请点这里 先设dp数组dp[i][j][k]表示数位是i,以j开头的数k出现的次数 有 ...