前言
比如“网盘”功能的实现,主要核心知识就是文件与I/O。
上传
JSP
-
input的type设置为“file”
-
form表单的method设置“post”(get只能拿到值为文件名的字符串)
-
form表单的enctype设置multipart/form-data,以二进制形式传输数据
-
代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>上传</title>
</head>
<body>
<form method="post" action="/upload" enctype="multipart/form-data">
<input name="text" type="file"/>
<input type="submit" value="上传"/>
</form>
</body>
</html>
Servlet
-
文件尽量保持字节流,避免所有编码问题(字节是最小单位,字符可能会打乱文件字节状态)
-
输入流:字节流 —— 字符流 —— 缓冲字符流
- --------- —— [ ] —— 【 】(不停嵌套加粗,读写速度、容量增加)
-
获取输出文件夹的绝对路径,并且要自己在工程的out里面创建,跟WEB-INF同一目录
-
输出流:同上
-
本质:通过输入流把用户上传文件读入JVM内存,再通过输出流输出到工程文件夹下
-
底层方法实现代码:
package com.microsoft.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
@WebServlet("/upload")
public class UploadServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 通过输入流获取客户端传来的数据流
InputStream inputStream = req.getInputStream();
Reader reader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(reader);
// 通过输出流将数据流输出到本地硬盘
// 获取文件夹的绝对路径
String path = req.getServletContext().getRealPath("file/copy.txt");
OutputStream outputStream = new FileOutputStream(path);
Writer writer = new OutputStreamWriter(outputStream);
BufferedWriter bufferedWriter = new BufferedWriter(writer);
// 边读边写
String str = "";
while((str = bufferedReader.readLine())!=null){
bufferedWriter.write(str);
System.out.println(str);
}
// 关闭流
bufferedWriter.close();
writer.close();
outputStream.close();
bufferedReader.close();
reader.close();
inputStream.close();
}
}
- 缺点
- 有一些我们不要的信息(头、尾)会被加入
- OOP思想的缺乏
- 实际开发时使用工具——fileupload
- 导入jar包
- commons-io
- commons-fileupload
- 将所有请求信息解析成FileItem对象,对该对象操作即可【OOP思想】
- 导入jar包
- 代码
package com.microsoft.servlet;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;
@WebServlet("/upload")
public class UploadServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
List<FileItem> list = servletFileUpload.parseRequest(req);
for (FileItem fileItem : list){
if(fileItem.isFormField()){// 是个框
String name = fileItem.getFieldName();
String value = fileItem.getString("UTF-8");
System.out.println(name+":"+value);
}else{// 是个文件
String fileName = fileItem.getName();
long size = fileItem.getSize();
System.out.println(fileName+":"+size+"Byte");
InputStream inputStream = fileItem.getInputStream();
String path = req.getServletContext().getRealPath("file/"+fileName);
OutputStream outputStream = new FileOutputStream(path);
int temp = 0;
while((temp = inputStream.read()) != -1){
outputStream.write(temp);
}
outputStream.close();
inputStream.close();
System.out.println("上传成功!");
}
}
} catch (FileUploadException e) {
e.printStackTrace();
}
}
}
下载
- JSP
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>下载</title>
</head>
<body>
<a href="/download?type=png">图片</a>
<a href="/download?type=txt">文本</a>
</body>
</html>
- Servlet
package com.microsoft.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@WebServlet("/download")
public class DownloadServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 设置响应方式,调用浏览器下载
resp.setContentType("application/x-msdownload");
String type = req.getParameter("type");
String filename = "";
switch (type){
case "png":
filename = "1.png";
break;
case "txt":
filename = "test.txt";
break;
}
// 设置下载好后的文件名
resp.setHeader("Content-Disposition","attachment;filename="+filename);
// 流处理
OutputStream outputStream = resp.getOutputStream();
String path = req.getServletContext().getRealPath("file/"+filename);
InputStream inputStream = new FileInputStream(path);
int temp = 0;
while((temp = inputStream.read()) != -1){
outputStream.write(temp);
}
// 关闭流
inputStream.close();
outputStream.close();
}
}