使用JSP/Servlet简单实现文件上传与下载

   通过学习黑马jsp教学视频,我学会了使用jsp与servlet简单地实现web的文件的上传与下载,首先感谢黑马。好了,下面来简单了解如何通过使用jsp与servlet实现文件上传与下载。
       在写代码之前,我们需要导入两个额外的jar包,一个是common-io-2.2.jar,另一个是commons-fileupload-1.3.1.jar,将这个两个jar 包导入WEB-INF/lib目录里。
       首先,想要在web端即网页上实现文件上传,必须要提供一个选择文件的框,即设置一个<input type="file"/>的元素,光有这个还不行,还需要对<input>元素外的表单form进行设置,将form的enctype属性设置为“multipart/form-data”,即<form action="" method="post" enctype="multipart/form-data">,当然请求方式也必须是post。让我们来简单做一个上传的jsp页面:
 
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>文件上传</title> <meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
--> </head> <body>
<form action="${pageContext.request.contextPath}/servlet/UploadServlet" method="post" enctype="multipart/form-data">
name:<input name="name"/><br/>
file1:<input type="file" name="f1"/><br/> <input type="submit" value="上传">
</form>
</body>
</html>

jsp页面做好之后,我们就要写一个UploadServlet,在编写上传servlet时,我们需要考虑到如果上传的文件出现重名的情况,以及上传的文件可能会出现的乱码情况,所以我们需要编码与客户端一致,并且根据文件名的hashcode计算存储目录,避免一个文件夹中的文件过多,当然为了保证服务器的安全,我们将存放文件的目录放在用户直接访问不到的地方,比如在WEB-INF文件夹下创建一个file文件夹。具体做法如下:

public class UploadServlet extends HttpServlet {  

    public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
System.out.print(request.getRemoteAddr());
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if(!isMultipart){
throw new RuntimeException("请检查您的表单的enctype属性,确定是multipart/form-data");
}
DiskFileItemFactory dfif = new DiskFileItemFactory();
ServletFileUpload parser = new ServletFileUpload(dfif); parser.setFileSizeMax(3*1024*1024);//设置单个文件上传的大小
parser.setSizeMax(6*1024*1024);//多文件上传时总大小限制 List<FileItem> items = null;
try {
items = parser.parseRequest(request);
}catch(FileUploadBase.FileSizeLimitExceededException e) {
out.write("上传文件超出了3M");
return;
}catch(FileUploadBase.SizeLimitExceededException e){
out.write("总文件超出了6M");
return;
}catch (FileUploadException e) {
e.printStackTrace();
throw new RuntimeException("解析上传内容失败,请重新试一下");
} //处理请求内容
if(items!=null){
for(FileItem item:items){
if(item.isFormField()){
processFormField(item);
}else{
processUploadField(item);
}
}
} out.write("上传成功!");
}
private void processUploadField(FileItem item) {
try {
String fileName = item.getName(); //用户没有选择上传文件时
if(fileName!=null&&!fileName.equals("")){
fileName = UUID.randomUUID().toString()+"_"+FilenameUtils.getName(fileName); //扩展名
String extension = FilenameUtils.getExtension(fileName);
//MIME类型
String contentType = item.getContentType(); //分目录存储:日期解决
// Date now = new Date();
// DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
//
// String childDirectory = df.format(now); //按照文件名的hashCode计算存储目录
String childDirectory = makeChildDirectory(getServletContext().getRealPath("/WEB-INF/files/"),fileName); String storeDirectoryPath = getServletContext().getRealPath("/WEB-INF/files/"+childDirectory);
File storeDirectory = new File(storeDirectoryPath);
if(!storeDirectory.exists()){
storeDirectory.mkdirs();
}
System.out.println(fileName);
item.write(new File(storeDirectoryPath+File.separator+fileName));//删除临时文件 }
} catch (Exception e) {
throw new RuntimeException("上传失败,请重试");
} }
//计算存放的子目录
private String makeChildDirectory(String realPath, String fileName) {
int hashCode = fileName.hashCode();
int dir1 = hashCode&0xf;// 取1~4位
int dir2 = (hashCode&0xf0)>>4;//取5~8位 String directory = ""+dir1+File.separator+dir2;
File file = new File(realPath,directory);
if(!file.exists())
file.mkdirs(); return directory;
}
private void processFormField(FileItem item) {
String fieldName = item.getFieldName();//字段名
String fieldValue;
try {
fieldValue = item.getString("UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("不支持UTF-8编码");
}
System.out.println(fieldName+"="+fieldValue);
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
} }

至此,上传的任务就基本完成了,有了上传当然也要有下载功能,在下载之前,我们需要将所有已经上传的文件显示在网页上,通过一个servlet与一个jsp页面来显示,servlet代码如下:

public class ShowAllFilesServlet extends HttpServlet {  

    public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String storeDirectory = getServletContext().getRealPath("/WEB-INF/files");
File root = new File(storeDirectory); //用Map保存递归的文件名:key:UUID文件名 value:老文件名
Map<String, String> map = new HashMap<String, String>();
treeWalk(root,map); request.setAttribute("map", map);
request.getRequestDispatcher("/listFiles.jsp").forward(request, response);
}
//递归,把文件名放到Map中
private void treeWalk(File root, Map<String, String> map) {
if(root.isFile()){
String fileName = root.getName();//文件名
String oldFileName = fileName.substring(fileName.indexOf("_")+1);
map.put(fileName, oldFileName);
}else{
File fs[] = root.listFiles();
for(File file:fs){
treeWalk(file, map);
}
} } public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
} }

通过上面的servlet转发到listFiles.jsp页面,listFiles.jsp页面:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>title</title> <meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
--> </head> <body>
<h1>以下资源可供下载</h1>
<c:forEach items="${map}" var="me">
<c:url value="/servlet/DownloadServlet" var="url">
<c:param name="filename" value="${me.key}"></c:param>
</c:url>
${me.value} <a href="${url}">下载</a><br/>
</c:forEach>
</body>
</html>

到这里,文件也显示出来了,就需要点击下载进行下载文件了,最后一步,我们再编写一个DownloadServlet:

public class DownloadServlet extends HttpServlet {  

    public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String uuidfilename = request.getParameter("filename");//get方式提交的
uuidfilename = new String(uuidfilename.getBytes("ISO-8859-1"),"UTF-8");//UUID的文件名 String storeDirectory = getServletContext().getRealPath("/WEB-INF/files");
//得到存放的子目录
String childDirecotry = makeChildDirectory(storeDirectory, uuidfilename); //构建输入流
InputStream in = new FileInputStream(storeDirectory+File.separator+childDirecotry+File.separator+uuidfilename);
//下载
String oldfilename = uuidfilename.substring(uuidfilename.indexOf("_")+1);
//通知客户端以下载的方式打开
response.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode(oldfilename, "UTF-8")); OutputStream out = response.getOutputStream(); int len = -1;
byte b[] = new byte[1024];
while((len=in.read(b))!=-1){
out.write(b,0,len);
}
in.close();
out.close(); } public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
//计算存放的子目录
private String makeChildDirectory(String realPath, String fileName) {
int hashCode = fileName.hashCode();
int dir1 = hashCode&0xf;// 取1~4位
int dir2 = (hashCode&0xf0)>>4;//取5~8位 String directory = ""+dir1+File.separator+dir2;
File file = new File(realPath,directory);
if(!file.exists())
file.mkdirs(); return directory;
}
}

文件上传与下载就已经全部完成了。

本文来源于 http://blog.csdn.net/wetsion/article/details/50890031

使用jsp/servlet简单实现文件上传与下载的更多相关文章

  1. 【Demo Project】AjaxSubmit+Servlet表单文件上传和下载

    一.背景 前段时间公司要求我做一个上传和下载固件的页面,以备硬件产品在线升级,现在我把这部分功能抽取出来作为一个Demo Project给大家分享. 话不多说,先看项目演示 --> 演示  源码 ...

  2. 简单的文件上传的下载(动态web项目)

    1.在页面中定义一个form表单,如下: <!-- 文件上传 --> <form action="${pageContext.request.contextPath}/Fi ...

  3. SSM简单实现文件上传和下载

    一.配置spring-mvc <!-- 配置多媒体文件解析器 --> <bean id="multipartResolver" class="org.s ...

  4. spring mvc 简单的文件上传与下载

    上传文件有很多种方法,这里主要讲解的是spring mvc内提供的文件上传 前提使用:spring mvc 在这个之前我们需要把环境给配置好 1:springmvc的XML配置文件加上这一段就即可, ...

  5. linux下安装简单的文件上传与下载工具 lrzsz

    编译安装 1.从下面的网站下载 lrzsz-1.12.20.tar.gz wget https://ohse.de/uwe/releases/lrzsz-0.12.20.tar.gz 2.查看里面的I ...

  6. java代码实现ftp服务器的文件上传和下载

    java代码实现文件上传到ftp服务器: 1:ftp服务器安装: 2:ftp服务器的配置: 启动成功: 2:客户端:代码实现文件的上传与下载: 1:依赖jar包: 2:sftpTools   工具类: ...

  7. ASP.NET 文件上传于下载

    本文主要介绍一下,在APS.NET中文件的简单上传于下载,上传是将文件上传到服务器的指定目录下,下载是从存入数据库中的路径,从服务器上下载. 1.上传文件 (1)页面代码 <table alig ...

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

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

  9. 基于jsp的文件上传和下载

    参考: 一.JavaWeb学习总结(五十)--文件上传和下载 此文极好,不过有几点要注意: 1.直接按照作者的代码极有可能listfile.jsp文件中 <%@taglib prefix=&qu ...

随机推荐

  1. JavaScript中的函数表达式

    在JavaScript中,函数是个非常重要的对象,函数通常有三种表现形式:函数声明,函数表达式和函数构造器创建的函数. 本文中主要看看函数表达式及其相关的知识点. 函数表达式 首先,看看函数表达式的表 ...

  2. [转]Oracle 修改或者删除临时表 ORA-14452: 试图创建, 更改或删除正在使用的临时表中的索引

    本文转自:http://blog.csdn.net/treasurelifelhf/article/details/7290729 由于存储过程出现问题,导致前台页面无法显示数据.执行存储过程发现临时 ...

  3. AC日记——质因数分解 1.5 43

    43:质因数分解 总时间限制:  1000ms 内存限制:  65536kB 描述 已知正整数 n 是两个不同的质数的乘积,试求出较大的那个质数. 输入 输入只有一行,包含一个正整数 n. 对于60% ...

  4. OAuth2学习及DotNetOpenAuth部分源码研究

    OAuth2学习及DotNetOpenAuth部分源码研究 在上篇文章中我研究了OpenId及DotNetOpenAuth的相关应用,这一篇继续研究OAuth2. 一.什么是OAuth2 OAuth是 ...

  5. [记录]ASP.NET MVC 2.0 如何使用Html.RadioButtonFor?

    在MVC 2.0里支持强类型实体绑定,可以直接使用如 <%: Html.TextBoxFor(model => model.Description, new { @class=" ...

  6. [No000046]为什么跳槽加薪会比内部调薪要高?

    有网友在知乎提问: 最近在思考一个问题,为什么跳槽往往意味着加薪? 如果一个人确有价值,为什么在原来的公司没有在薪水上体现出来?如果没有价值,为什么跳槽以后就会加薪?还是可以单纯的解释为,应聘者和招聘 ...

  7. html-webpack-plugin插件的详细介绍和使用

    var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exp ...

  8. listview1

    Edit1.Text := listview1.Items[i].Caption; //读第i行第1列 Edit2.Text := listview1.Items[i].SubItems.string ...

  9. Splay整理

    伸展树(Splay Tree),也叫分裂树,是一种二叉排序树,它能在O(log n)内完成插入.查找和删除操作.(来自百科) 伸展树的操作主要是

  10. java中wait/notify机制

    通常,多线程之间需要协调工作.例如,浏览器的一个显示图片的线程displayThread想要执行显示图片的任务,必须等待下载线程 downloadThread将该图片下载完毕.如果图片还没有下载完,d ...