上传

使用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. android 编译环境 & 开发教程 【持续更新】

    一. 优秀博文推荐 1.ubuntu 搭建 android源码编译环境 ubuntu14.04LTS android 源码编译环境的搭建 2.开源网站 2.android 开源 网站 2015最流行的 ...

  2. CUDA Samples: Julia

    以下CUDA sample是分别用C++和CUDA实现的绘制Julia集曲线,并对其中使用到的CUDA函数进行了解说,code参考了<GPU高性能编程CUDA实战>一书的第四章,各个文件内 ...

  3. Why ZK

    ZooKeeper是一个开放源代码的分布式协调服务,由知名互联网公司雅虎创建,是Google Chubby的开源实现.ZooKeeper的设计目标是将那些复杂且容易出错的分布式一致性服务封装起来,构成 ...

  4. Leetcode 590. N-ary Tree Postorder Traversal

    DFS,递归或者栈实现. """ # Definition for a Node. class Node: def __init__(self, val, childre ...

  5. HDU 1806

    http://acm.hdu.edu.cn/showproblem.php?pid=1806 非常玄妙的rmq问题,这个st算法有点神 #include <iostream> #inclu ...

  6. sift特征简述

    参考文献:http://blog.csdn.net/abcjennifer/article/details/7639681 分为几个步骤: 1. 构建尺度空间 2. LoG近似DoG找到关键点< ...

  7. erlang开发环境配置

    第一步  从源码安装erlang git clone https://github.com/erlang/otp 目前最新版本为17.X cd otp/ ./configer  检查编译环境 sudo ...

  8. Bezier曲线原理—动态解释

    公式线性公式给定点P0.P1,线性贝兹曲线只是一条两点之间的直线.且其等同于线性插值.这条线由下式给出: 一阶贝赛尔曲线上的由两个点确定 P0 和P1,当t在0--->1区间上递增时,根据此会得 ...

  9. JS 快速获取数据中的最大、最小值

    var  numbers = [5,23 , 1420 , 5215 , 228 , 400 , 105, 411]; var maxInNumbers = Math.max.apply(Math, ...

  10. 每天一个linux命令(文件操作):【转载】find 命令概览

    Linux下find命令在目录结构中搜索文件,并执行指定的操作.Linux下find命令提供了相当多的查找条件,功能很强大.由于find具有强大的功能,所以它的选项也很多,其中大部分选项都值得我们花时 ...