Servlet文件上传和下载的复习
上传
使用Servlet完成上传和下载相较于使用Struts框架有点麻烦,毕竟更偏底层了
项目中主要使用的jar包:
commons-io-2.2.jar commons-fileupload-1.3.2.jar
其他使用的jar有:
commons-beanutils-1.8.3.jar commons-logging-1.1.1.jar itcast-tools-1.4.2.jar
页面:
<body>
<form action="<c:url value='/uploadServlet3'/>" method="POST" enctype="multipart/form-data">
照 片:<input type="file" name="zhaopian"/><br/>
<input type="submit" value="提交"/>
</form>
值得注意的是:form要使用post提交,并使用enctype,这和使用Struts的页面要求是一致的
上传文件四步骤
1.创建工厂(DiskFileItemFactory)
2.根据工厂创建解析器(ServletFileUpload)
3.解析request,得到FileItem集合
4.遍历FileItem,调用其API完成操作
我将文件保存在WEB-INF中,这样的话通过浏览器是直接访问不到这个资源的,在WEB-INF中还使用了根据文件名的哈希名称前两个首字母生成目录来存放,对了,这个文件名还用了UUID值+_+文件名的方式避免同名问题,对于部分浏览器可能出现据对路径的问题也进行了处理
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import cn.itcast.commons.CommonUtils; public class UploadServlet3 extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
} public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
//前三步
//DiskFileItemFactory factory=new DiskFileItemFactory();
//可以使用临时目录(d:/temp需先创建)和设置缓存大小(20kb)
DiskFileItemFactory factory=new DiskFileItemFactory(20*1024,new File("d:/temp"));
ServletFileUpload fileUpload=new ServletFileUpload(factory);
List<FileItem> list = fileUpload.parseRequest(req); FileItem fi1 = list.get(1);
//得到文件保存的路径(files目录需创建)
String root = this.getServletContext().getRealPath("/WEB-INF/files/");
//处理绝对路径问题
String fileName=fi1.getName();
int index=fileName.lastIndexOf("//");
if(index!=-1){
fileName=fileName.substring(index+1);
} //处理重名问题
String saveFileName=CommonUtils.uuid()+"_"+fileName; //目录打散
//1.获得文件名的哈希值并转换为十六进制
int hashCode = fileName.hashCode();
String hex = Integer.toHexString(hashCode);
//2.获得十六进制的前两位,生成目录链
File dirFile=new File(root,hex.charAt(0)+"/"+hex.charAt(1));
dirFile.mkdirs();
//3.创建文件并保存
File desFile=new File(dirFile,saveFileName);
fi1.write(desFile);
} catch (Exception e) {
e.printStackTrace();
} } }
这里使用了CommonUtils类来生成UUID值,这个类是在itcast-tools-1.4.2.jar(传智播客提供)
下载
下载所使用的jar包是:commons-io-2.2.jar
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
import sun.misc.BASE64Encoder; public class DownloadServlet extends HttpServlet { public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/*
* 文件下载,两个头一个流
* 响应头1:Content-Type
* 响应头2:Content-Disposition
* 流:下载文件数据
*/
String fileName="e:/IBelieve.mp3"; //文件所在位置
String frameName=filenameEncoding("%IBelieve%.mp3", req); //下载时显示的文件名
String contentType=this.getServletContext()
.getMimeType(fileName); //通过文件名得到MIME类型
String contentDisposition="attachment;filename="+frameName;
//一个流
FileInputStream inputStream=new FileInputStream(fileName);
//设置头
resp.setHeader("Content-Type", contentType);
resp.setHeader("Content-Disposition", contentDisposition);
//获取绑定了响应端的流
ServletOutputStream outputStream=resp.getOutputStream(); IOUtils.copy(inputStream, outputStream); //将输入流的数据写到输出流 inputStream.close(); } public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
} //用来对下载文件名进行编码
public static String filenameEncoding(String filename, HttpServletRequest request) throws IOException {
String agent = request.getHeader("User-Agent"); //获取浏览器
if (agent.contains("Firefox")) {
BASE64Encoder base64Encoder = new BASE64Encoder();
filename = "=?utf-8?B?"
+ base64Encoder.encode(filename.getBytes("utf-8"))
+ "?=";
} else if(agent.contains("MSIE")) {
filename = URLEncoder.encode(filename, "utf-8");
} else {
filename = URLEncoder.encode(filename, "utf-8");
}
return filename;
}
}
filenameEncoding()方法可以根据浏览器的不同对下载的文件名进行编码,避免乱码
Servlet文件上传和下载的复习的更多相关文章
- java web学习总结(二十四) -------------------Servlet文件上传和下载的实现
在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...
- servlet文件上传及下载
servlet3.0中提供了对文件上传的直接支持,不需要借助任何第三方上传组件,直接使用Servlet3.0提供的API就能够实现文件上传功能. servlet 代码: package ni.jun. ...
- 使用jsp/servlet简单实现文件上传与下载
使用JSP/Servlet简单实现文件上传与下载 通过学习黑马jsp教学视频,我学会了使用jsp与servlet简单地实现web的文件的上传与下载,首先感谢黑马.好了,下面来简单了解如何通过使用 ...
- springmvc和servlet在上传和下载文件(保持文件夹和存储数据库Blob两种方式)
参与该项目的文件上传和下载.一旦struts2下完成,今天springmvc再来一遍.发现springmvc特别好包,基本上不具备的几行代码即可完成,下面的代码贴: FileUpAndDown.jsp ...
- Servlet文件上传下载
今天我们来学习Servlet文件上传下载 Servlet文件上传主要是使用了ServletInputStream读取流的方法,其读取方法与普通的文件流相同. 一.文件上传相关原理 第一步,构建一个up ...
- (转载)JavaWeb学习总结(五十)——文件上传和下载
源地址:http://www.cnblogs.com/xdp-gacl/p/4200090.html 在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传 ...
- JavaWeb学习总结,文件上传和下载
在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...
- java文件上传和下载
简介 文件上传和下载是java web中常见的操作,文件上传主要是将文件通过IO流传放到服务器的某一个特定的文件夹下,而文件下载则是与文件上传相反,将文件从服务器的特定的文件夹下的文件通过IO流下载到 ...
- JavaWeb学习总结(五十)——文件上传和下载
在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...
随机推荐
- etl工具-Bireme
前段时间做数据仓库项目,自己实现了一部分etl功能,后面一直没有时间去深入挖掘.这个工具貌似不错,写个帖子做下记录: https://hashdatainc.github.io/bireme/READ ...
- 关于block和inline元素的float
CSS float 浮动属性 本篇主要介绍float属性:定义元素朝哪个方向浮动. 目录 1. 页面布局方式:介绍文档流.浮动层以及float属性. 2. float:left :介绍float为 l ...
- TF随笔-11
#!/usr/bin/env python2 # -*- coding: utf-8 -*- import tensorflow as tf my_var=tf.Variable(0.) step=t ...
- [Python] 项目打包发布
一.setuptools - 官方文档: Building and Distributing Packages with Setuptools- 中文文档: Python包管理工具setuptools ...
- POJ 1951
把给定字符串翻译成目标字符串需要满足的条件是: 1.开头不能有空格 2.末尾不能有空格 3.给定标点前不能有空格 4.不能有A.E.I.O.U 5.空格不能和空格相邻 6.相同的字母只能出现1次 给出 ...
- Unity Obstacle分析
NavMeshObstacle Normal 通过设置半径和高度来设定障碍物,配合NavMesh使用. 优点: 简单易用,效率高 动态生成 缺点: 可能会被主角穿过,但目前没发现 形状固定为圆柱 Na ...
- BZOJ2687 交与并/BZOJ2369 区间【决策单调性优化DP】【分治】
Description 对于一个区间集合 {A1,A2--Ak}(K>1,Ai不等于Aj(i不等于J),定义其权值 S=|A1∪A2∪--AK|*|A1∩A2--∩Ak| 即它们的交区间的长度乘 ...
- BZOJ2002 Hnoi2010 Bounce 弹飞绵羊 【LCT】【分块】
BZOJ2002 Hnoi2010 Bounce 弹飞绵羊 Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始, ...
- MySQL实战 | 04 为什么要使用索引?
原文链接:MySQL实战 | 为什么要使用索引? 用过 MySQL 的应该都知道索引是干啥的吧,应该多少都设置过索引,但是若是问你索引是怎么实现的,你能说上来吗? 索引是什么? MySQL 官方对索引 ...
- python正则的使用
python的正则是通过re模块的支持 匹配的3个函数 match :只从字符串的开始与正则表达式匹配,匹配成功返回matchobject,否则返回none: re.match(pattern, st ...