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中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...
随机推荐
- L166
THE idea of underwater mining is not restricted to the ocean floor (see article). High water tables ...
- 重写alert 方法(我胡汉三又回来了)
window.alert = function (txt) { var shield = document.createElement("DIV"); shield.id = &q ...
- 真机调试watch的一系列bug
真机调试watch的一系列bug 系列一 WatchKit 2.0 app's bundle ID com.jiaoshi.memoKB is not prefixed by the parent a ...
- Git详解之四 服务器上的Git
以下内容转载自:http://www.open-open.com/lib/view/open1328069988843.html 服务器上的 Git 到目前为止,你应该已经学会了使用 Git 来完成日 ...
- 一个导出redis有序集合sorted-sets的shell脚本
通过keys匹配需要导出的有序集合名称,这些集合命名格式为:*_010_09/Dec/2015 依次通过zscan导出有序集合中的数据,并分别保存 #/bin/shzset_pattern=”*_01 ...
- 【测试工具】tcpdump + wireshark 抓包实践
Tcpdump + Wireshark 抓包实践 工具介绍 Tcpdump 看到dump大家应该有所意识吧,就是下载数据,抓数据.tcpdump是linux下的一个抓取tcp包的命令 Usage: t ...
- Sprint Boot 学习Q&A
[ERROR] Failed to execute goal pl.project13.maven:git-commit-id-plugin:2.1.11:revision (default) on ...
- 编程之美Ex2——字符串移位包含的问题
给定两个字符串s1,s2,要求判定s2是否能够被s1做循环移位得到的字符串包含. 例如, 给定s1=AABCD和s2=CDAA,返回true: 给定s1=ABCD和s2=ACBD,返回false. 法 ...
- 线性回归 Linear regression(3) 线性回归的概率解释
这篇博客从一种方式推导了Linear regression 线性回归的概率解释,内容来自Standford公开课machine learning中Andrew老师的讲解. 线性回归的概率解释 在Lin ...
- 使用python处理selenium中的xpath定位元素的模糊匹配问题
# 用contains,寻找页面中style属性值包含有sp.gif这个关键字的所有div元素,其中@后面可以跟该元素任意的属性名. self.driver.find_element_by_xpath ...