上传

使用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文件上传和下载的复习的更多相关文章

  1. java web学习总结(二十四) -------------------Servlet文件上传和下载的实现

    在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...

  2. servlet文件上传及下载

    servlet3.0中提供了对文件上传的直接支持,不需要借助任何第三方上传组件,直接使用Servlet3.0提供的API就能够实现文件上传功能. servlet 代码: package ni.jun. ...

  3. 使用jsp/servlet简单实现文件上传与下载

    使用JSP/Servlet简单实现文件上传与下载    通过学习黑马jsp教学视频,我学会了使用jsp与servlet简单地实现web的文件的上传与下载,首先感谢黑马.好了,下面来简单了解如何通过使用 ...

  4. springmvc和servlet在上传和下载文件(保持文件夹和存储数据库Blob两种方式)

    参与该项目的文件上传和下载.一旦struts2下完成,今天springmvc再来一遍.发现springmvc特别好包,基本上不具备的几行代码即可完成,下面的代码贴: FileUpAndDown.jsp ...

  5. Servlet文件上传下载

    今天我们来学习Servlet文件上传下载 Servlet文件上传主要是使用了ServletInputStream读取流的方法,其读取方法与普通的文件流相同. 一.文件上传相关原理 第一步,构建一个up ...

  6. (转载)JavaWeb学习总结(五十)——文件上传和下载

    源地址:http://www.cnblogs.com/xdp-gacl/p/4200090.html 在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传 ...

  7. JavaWeb学习总结,文件上传和下载

    在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...

  8. java文件上传和下载

    简介 文件上传和下载是java web中常见的操作,文件上传主要是将文件通过IO流传放到服务器的某一个特定的文件夹下,而文件下载则是与文件上传相反,将文件从服务器的特定的文件夹下的文件通过IO流下载到 ...

  9. JavaWeb学习总结(五十)——文件上传和下载

    在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...

随机推荐

  1. .net 枚举(Enum)使用总结

    在实际问题中,有些变量的取值被限定在一个有限的范围内.例如,一个星期内只有七天,一年只有十二个月,性别只有男跟女等等.如果把这些量说明为整型.字符型或其它类型显然是不妥当的.为此,C#提供了一种称为“ ...

  2. C# 如何判断字符串中是否包含另一个字符串?

    如  字符串1(str1)为:“你好怎么解决呢!”    字符串2(str2)为:“你好” 如果str1里面包str2 则 Response.Write("成功");否则 Resp ...

  3. ng-if 判断条件中不能 使用变量名字拼接,switch可以

  4. Xcode 8 修改项目名

    很麻烦,不想修改了 有个教程,贴一下. From: 大发写字的地方 Xcode8 修改包名(含cocopods)

  5. 编程之美Ex1——求二进制中1的个数

    又被阿里机考虐了一次,决定改变策略开始刷题T^T 一个字节(8bit)的无符号整型,求其二进制中的“1”的个数,算法执行效率尽可能高. 最先想到的移位操作,末尾位&00000001,然后右移, ...

  6. 解决 git 错误 error: RPC failed; curl 56 OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 11

    环境 Windows 7 . git push 时出现错误,无法提交代码到远程仓库. Counting objects: , done. Delta compression using up to t ...

  7. POJ3422 Kaka's Matrix Travels 【费用流】*

    POJ3422 Kaka's Matrix Travels Description On an N × N chessboard with a non-negative number in each ...

  8. BZOJ1857 Scoi2010 传送带 【三分】

    BZOJ1857 Scoi2010 传送带 Description 在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段.两条传送带分别为线段AB和线段CD.lxhgww在AB上的移动速度为P ...

  9. 重温CLR(十四) 可空类型

    我们知道,一个值类型的变量永远不可能为null.它总是包含值类型本身.遗憾的是,这在某些情况下会成为问题.例如,设计一个数据库时,可将一个列定义成为一个32位的整数,并映射到FCL的Int32数据类型 ...

  10. MySQL优化之表结构优化的5大建议

    很多人都将 数据库设计范式 作为数据库表结构设计“圣经”,认为只要按照这个范式需求设计,就能让设计出来的表结构足够优化,既能保证性能优异同时还能满足扩展性要求殊不知,在N年前被奉为“圣经”的数据库设计 ...