文件的上传和下载
文件的上传
1.创建项目,导入如下两个包
2.在WebContent中创建上传表单form.jsp
form表单中
enctype属性值需要设置为 enctype=“multipart/form-data”
method属性值需要设置为 method=“post”
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>文件上传</title>
</head>
<body>
<form action="UploadServlet" method="post"
enctype="multipart/form-data">
<table width="600px">
<tr>
<td>上传者</td>
<td><input type="text" name="name"></td>
</tr>
<tr>
<td>上传文件</td>
<td><input type="file" name="myfile"></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="上传"></td>
</tr>
</table>
</form>
</body>
</html>
3.创建上传Servlet。
在src文件夹下创建fileupload包并创建UploadServlet类
package fileupload;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.List;
import java.util.UUID;
import javax.management.RuntimeErrorException;
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;
/**
* Servlet implementation class UploadServlet
*/
public class UploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
// 设置ContentType字段值
response.setContentType("text/html;charset=utf-8");
// 创建DiskFileItemFactory对象(用于将请求消息实体中的每一个文件封装成单独的FileItem对象)
DiskFileItemFactory factory = new DiskFileItemFactory();
// 设置文件缓存目录,如果该目录不存在则新创建一个
File f = new File("D:\\TempFolder");
if (f.exists()) {// 判断一个文件是否存在
f.mkdirs();// 用于创建指定路径名称对应的目录
}
// 设置文件的缓存路径
factory.setRepository(f);
// 创建ServletFileUpload对象(处理文件上传的核心高级类)
ServletFileUpload fileupload = new ServletFileUpload(factory);
// 设置字符编码
fileupload.setHeaderEncoding("utf-8");
// 解析request,得到上传文件的FileItem对象
// FileItem接口:主要用于封装单个表单字段元素的数据,一个表单字段元素对应一个FileItem对象
// parseRequest(request)将HTML中每个表单提交的数据封装成一个FileItem对象,并以List列表形式返回
List<FileItem> fileitems = fileupload.parseRequest(request);// 一定要导包,用默认包报错报错
// 获取字符流
PrintWriter writer = response.getWriter();
// 遍历集合
for (FileItem fileitem : fileitems) {
// isFormField()判断fileitem是普通文本字段还是文件表单字段,如果是普通文本表单字段则返回true
if (fileitem.isFormField()) {
// 如果是普通文本的,获取字段名和字段值
String name = fileitem.getFieldName();// 获取表单中“name”属性的值
if (name.equals("name")) {
// 如果文件不为空,则将其保存到value中
if (!fileitem.getString().equals("")) {// getString()将FileItem对象中的数据流内容以字符串返回
String value = fileitem.getString("utf-8");
writer.print("上传者:" + value + "<br>");
}
}
} else {// 不是普通文本字段,则进行上传操作
// 获取文件名
String filename = fileitem.getName();// 获取表单中“name”属性的值
// 处理上传文件
if (filename != null && !filename.equals("")) {// 判断文件名字是否为空
writer.print("<br>上传的文件名称是:" + filename + "<br>");
// 截取出文件名
/*
* substring()截取字符串的一段,可以指定开始截取处索引,也可以同时指定开始和停止截取处索引
* lastIndexOf("字符串参数")返回字符串最后出现的位置
*/
filename = filename.substring(filename.lastIndexOf("\\") + 1);
// 唯一文件名
// randomUUID()产生唯一id
filename = UUID.randomUUID().toString() + "_" + filename;
// 在服务器创建同名文件
String webpath = "/upload/";
// 将服务器中的文件夹路径与文件名组合成完整的服务器端路径
// getServletContext()返回一个代表当前web应用的ServletContext对象
// getRealPath()使用当前项目作为根目录
String filepath = getServletContext().getRealPath(webpath + filename);
// 创建文件
File file = new File(filepath);
/*
* getParentFile()的作用是获得父目录 问题就是.mkdirs();
* 这个方法只能生成一层一层的文件夹,不能生成文件,而你的file对象路径是直接到文件那一层的,
* 不用getParentFile()获得父目录的话,就会生成两个文件夹而不是你想要的文件, 所以要先调用getParentFile()获得父目录,
* 用.mkdirs()生成父目录文件夹, 最后把你想要的文件生成到这个文件夹下面,就是想要的结果
*/
file.getParentFile().mkdirs();
file.createNewFile();// 把你想要的文件生成到这个文件夹下面
// 获得上传流
InputStream in = fileitem.getInputStream();
// 使用FileOutputStream打开服务器端的上传文件
FileOutputStream out = new FileOutputStream(file);
// 流的对拷
byte[] buffer = new byte[1024];
int len;
// 开始读取上传文件的字符,并将其输出到服务器端
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);// 写入文件
}
// 关闭流
in.close();
out.close();
// 删除临时文件
fileitem.delete();
writer.print("文件上传成功!<br>");
writer.print("上传路径是:" + filepath + "<br>");
} else {
writer.print("文件上传失败!<br>");
}
}
}
} catch (Exception e) {
// TODO: handle exception
throw new RuntimeException(e);
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
4.运行结果:
根据目录找到上传的文件
注:自己在桌面或者自己易记的地方创建自己需要上传的文件夹
文件的下载
说明:
1.URLEncoder类
ServletAPI中提供了一个URLEncoder类,该类定义encode(String s,String enc)方法可以将URL中的字符串以指定的编码形式输出,该编码方式称为URL编码。HTTP消息头的数据只有经过URL编码成世界通用的符号后,才不会在传输过程中出现乱码问题。
2.创建文件夹,放入图片
在项目的WebContent目录下创建一个名称为download的文件夹,并放入一张图片(梦想.png)
1.创建download.jsp
download.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@page import="java.net.URLEncoder"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>下载页面</title>
</head>
<body>
<a href="/charpter12/DownloadServlet?filename=<%=URLEncoder.encode("梦想.png", "utf-8")%>">文件下载</a>
</body>
</html>
2.创建DownloadServlet类
在项目src的fileupload包中创建DownloadServlet类
package fileupload;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class DownloadServlet
*/
public class DownloadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public DownloadServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
// 设置响应消息编码
response.setCharacterEncoding("utf-8");
// 设置请求消息编码
request.setCharacterEncoding("utf-8");
// 获取所要下载的文件名称
String filename = request.getParameter("filename");
// 对文件名称编码
filename = new String(filename.trim().getBytes("iso8859-1"), "utf-8");
// 下载文件所在目录
String folder = "/download/";
// 通知浏览器以下载的方式打开
response.addHeader("Content-Type", "application/octet-stream");
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "utf-8"));
// 通过文件流读取文件
// getServletContext()返回一个代表当前web应用的ServletContext对象
InputStream in = getServletContext().getResourceAsStream(folder + filename);
// 获取response对象的输出流
OutputStream out = response.getOutputStream();
byte[] buffer = new byte[1024];
int len;
// 循环取出流中的数据
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
in.close();
out.close();
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
3.运行结果
1。运行download.jsp
2。下载提示
3,成功下载到桌面