文章目录
文件的上传和下载是非常常见的功能,在很多的系统或软件中都经常使用到。
例如:QQ头像的上传、邮箱中邮件的发送和接收、在浏览器中下载资源文件等等
一、文件上传
1、文件上传的介绍
1、创建一个form表单标签,设置method=post请求
2、from表单的encType属性值必须为multipart/form-data
3、在form标签中使用input type=file进行文件的添加
4、编写服务器代码接收并处理上传的文件
下面我们用代码演示该如何进行文件的上传
(1)up_file.jsp页面,用于上传文件
multipart/form-data
:表示提交的数据以多段(每一个表单项一个数据段)的形式进行拼接,然后以二进制流的形式发上给服务器
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="upFileServlet" method="post" enctype="multipart/form-data">
用户名:<input type="text" name="username"><br/>
头像:<input type="file" name="photo"><br/>
<input type="submit" value="上传">
</form>
</body>
</html>
(2)UpFileServlet类,用于接收客户端发来的请求
public class UpFileServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
writer.println("文件上传成功");
}
}
(3)web.xml文件
<servlet>
<servlet-name>UpFileServlet</servlet-name>
<servlet-class>servlet.UpFileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UpFileServlet</servlet-name>
<url-pattern>/upFileServlet</url-pattern>
</servlet-mapping>
向表单中填入数据并上传文件,然后我们在服务器端使用req.getParameter()
方法获取数据时,无法获得。我们在前面说过multipart/form-data
是以流的形式进行传输数据的,而我们的from表单正是用的这种形式,所以我们也应该用流的形式进行接收
以流的形式进行数据的接收并输出
ServletInputStream inputStream = req.getInputStream();
byte[] buffer = new byte[1024000] ;
int read = inputStream.read(buffer) ;
System.out.println(new String(buffer,0,read));
这里的 123456 是用户名的值,123123 是1.txt文件中的数据
2、上传文件的解析
(1)引入第三方的工具类commons-fileupload和commons-io
第一种方式,使用maven工程,在pom.xml文件中引入两个外部文件
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.4</version>
</dependency>
第二种方式是引入两个外部类的jar包
官网地址: http://commons.apache.org/proper/commons-fileupload/
(2)工具类中常用的类和方法
类
类 | 作用 |
---|---|
FIleItem类 | 表示每一个表单项 |
ServletFileUpload类 | 用于解析上传的数据 |
方法
方法 | 作用 |
---|---|
boolean ServletFileUpload.isMultipartContent(HttpServletRequest request) | 判断当前上传文件的数据格式是否是多段的 |
List<FileItem> parseRequest(HttpServletRequest request) | 解析上传的数据 |
boolean FileItem.isFormField() | 判断当前这个表单项是否是普通的表单项还是上传的文件类型的表单项 true表示普通的表单项 false表示文件类型的表单项 |
String FileItem.getFieldName() | 获取表单项的name属性值 |
String FileItem.getString() | 获取表单项的值 |
String FileItem.getName() | 获取上传的文件名 |
void FileItem.write(file) | 将上传的文件写到参数file所指向的磁盘的位置 |
(3)文件的上传
UpFileServlet类
public class UpFileServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1、判断上传的数据是否是多段数据的形式(当其是多段数据时可以得出它是文件的上传)
if(ServletFileUpload.isMultipartContent(req)) {
// 创建FileItemFactory工厂实现类
FileItemFactory fileItemFactory = new DiskFileItemFactory();
// 创建用于解析上传数据的工具类ServletFileUpload类
ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory);
try {
// 解析上传的数据,得到每一个表单项FileItem
List<FileItem> fileItems = servletFileUpload.parseRequest(req);
// 循环判断每一个表单项的类型,是普通类型还是上传的文件类型
for (FileItem fileItem : fileItems) {
if(fileItem.isFormField()) {
// 普通表单项
System.out.println("表单项的name属性值: " + fileItem.getFieldName());
// 参数为utf-8,防止出现乱码
System.out.println("表单项的value属性值: " + fileItem.getString("utf-8"));
} else {
// 上传的文件
System.out.println("表单项的name属性值: " + fileItem.getFieldName());
System.out.println("上传文件的文件名: " + fileItem.getName());
// 将上传文件保存到磁盘上
fileItem.write(new File(("C:\\Users\\Administrator\\IdeaProjects\\springmvc\\java_web-fileup_down\\src\\main\\webapp\\file\\") + fileItem.getName()));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
在浏览器中填写表单信息并提交,可以看到在控制台输出的表单的信息,以及1.txt文件被保存到了file目录下,说明文件上传成功了
二、文件下载
1、文件下载的介绍
客户端(浏览器):
向服务器发送请求表示要下载某个资源文件
服务器:
1、获取客户端要下载的文件名
2、读取要下载的文件的内容
3、通过响应头告诉客户端返回的数据的类型和数据是用于下载使用的
4、把要下载的文件内容回传给客户端
2、文件下载的实现
(1)创建DownFileServlet类,处理文件下载
public class DownFileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1、获取客户端要下载的文件名(自定义)
String fileName = "1.txt" ;
// 2、读取要下载的文件的内容(通过ServletContext对象读取)
ServletContext servletContext = getServletContext();
// 获取要下载的文件类型
String mimeType = servletContext.getMimeType("/file/" + fileName);
System.out.println("下载文件的类型 : " + mimeType);
// 3、通过响应头告诉客户端返回的数据的类型和数据是用于下载使用的
resp.setContentType(mimeType);
// Content-Disposition响应头,表示收到的数据怎么处理
// attachment表示附件,表示下载使用的
// filename表示指定下载的文件名
resp.setHeader("Content-Disposition","attachment;filename=" + fileName);
InputStream resourceAsStream = servletContext.getResourceAsStream("/file/" + fileName);
// 获取响应的输出流
ServletOutputStream outputStream = resp.getOutputStream();
// 4、读取输入流中数据复制给输出流,输出给客户端
IOUtils.copy(resourceAsStream,outputStream) ;
}
}
(2)结果
我们先从up_file.jsp页面上传过数据后,然后用浏览器去访问downFileServlet程序时,它会直接将该文件下载
3、解决文件名中文乱码
当我们将文件名改为中文时,再去访问servlet程序,发现下载的文件的文件名出现了中文乱码的情况
resp.setHeader("Content-Disposition","attachment;filename=" + URLEncoder.encode(fileName,"utf-8"));
设置响应头中的URL编码为utf-8,再次访问下载文件,可以看到文件名没出现乱码