文件上传下载
大家好呀,我是小笙!
web 应用常用功能 -文件上传下载
文件上传
文件上传下载需要使用到两个包 , 需要导入
表单提交
<!-- 表单的 enctype 属性要设置为 multipart/form-data -->
<!-- 表单默认为url编码是用来传输文本的,文件(二进制数据)需要另外一种编码方式来提交,因此是multipart分多个部分提交-->
<form action="xxxx" method="POST" enctype="multipart/form-data">
家居图: <img src="2.jpg" alt="" width="200" height="200" id="prevView">
<input type="file" name="pic" id="" value="2xxx.jpg" onchange="prev(this)"/>
家居名: <input type="text" name="name"><br/>
<input type="submit" value="上传"/>
</form>
获取文件上传请求
- 判断表单类型(multipart/form-data或者application/x-www-form-urlencoded)
- 假设是multipart/form-data类型
- 判断表单内的数据,是普通文本的表单项,则以文本形式处理
- 如果是文件表单项,则使用IO流保存到本地服务器的指定目录
- application/x-www-form-urlencoded类型则统一都用url解码来处理
代码示例
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<base href="<%=request.getContextPath()+"/"%>>">
<style type="text/css"> input[type="submit"] {
outline: none;
border-radius: 5px;
cursor: pointer;
background-color: #31B0D5;
border: none;
width: 70px;
height: 35px;
font-size: 20px;
}
img {
border-radius: 50%;
}
form {
position: relative;
width: 200px;
height: 200px;
}
input[type="file"] {
position: absolute;
left: 0;
top: 0;
height: 200px;
opacity: 0;
cursor: pointer;
} </style>
<script type="text/javascript">
function prev(event)
{
// 获取展示图片的区域
var img = document.getElementById("prevView");
// 获取文件对象
let file = event.files[0];
// 获取文件阅读器
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function ()
{
// 给img的src设置图片url
img.setAttribute("src", this.result);
}
}
</script>
</head>
<body>
<!-- 表单的 enctype 属性要设置为 multipart/form-data -->
<form action="fileServlet" enctype="multipart/form-data" method="post">
家居图: <img src="2.jpg" alt="" width="200" height="200" id="prevView">
<input type="file" name="pic" id="" value="2xxx.jpg" οnchange="prev(this)"/><br>
家居名: <input type="text" name="name"><br/><br/>
<input type="submit" value="上传"/>
</form>
</body>
</html>
// 工具类
public class Date {
public static String getLocalDate(){
LocalDateTime localDate = LocalDateTime.now();
return String.valueOf(localDate.getYear()) + "-" + String.valueOf(localDate.getMonth())
+ "-" + String.valueOf(localDate.getDayOfMonth());
}
}
// 文件下载类
@WebServlet(name = "FileUpload",urlPatterns = {"/fileServlet"})
public class FileUpload extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 判断请求格式是否是文件格式的
if(ServletFileUpload.isMultipartContent(request)){
System.out.println("文件传输");
// 创建DiskFileItemFactory对象,用于构建一个解析上传数据的工具对象
DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
// 创建一个解析上传数据的工具对象
ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
servletFileUpload.setHeaderEncoding("utf-8");
try {
List<FileItem> list = servletFileUpload.parseRequest(request);
// 遍历文件项
for (FileItem fileItem : list) {
String name;
if(!fileItem.isFormField()){
// 文件名
name = fileItem.getName();
// 指定图片保存的路径
String filePath = getServletContext().getRealPath("/images/" + Date.getLocalDate() + "/");
File file = new File(filePath);
// 该文件目录是否存在
if(!file.exists()){
file.mkdirs();
}
// 将文件数据存入到指定目录,同时通过UUID来确定文件不会重名
name = UUID.randomUUID().toString() + name;
fileItem.write(new File(filePath + name));
// 页面显示
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("<h1>上传成功!</h1>");
}else{
name = fileItem.getString("utf-8");
System.out.println(name);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}else{
System.out.println("普通文本传输");
}
}
}
注意事项
- 一个完美的文件上传,要考虑的因素很多,比如断点续传、控制图片大小,尺寸,分片 上传,防止恶意上传等,在项目中,可以考虑使用 WebUploader 组件
- 文件上传功能,在项目中建议有限制的使用,一般用在头像、证明、合同、产品展示等, 如果不加限制,会造成服务器空间被大量占用
文件下载
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件下载</title>
<base href="<%=request.getContextPath()+"/"%>>">
</head>
<body>
<h1>文件下载</h1>
<a href="download?dir=/imgs/&resource=1.png">点击下载java图片</a><br/>
<a href="download?dir=/word/&resource=2.doc">点击下载罗念笙笔记.doc</a>
</body>
</html>
@WebServlet(name = "Download",urlPatterns = {"/download"})
public class Download extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取下载的文件名字
request.setCharacterEncoding("utf-8");
String dir = request.getParameter("dir");
String fileName = request.getParameter("resource");
System.out.println(fileName);
String resourcePath = dir + fileName;
// 给http响应设置响应头 Content-Type
ServletContext servletContext = request.getServletContext();
String mimeType = servletContext.getMimeType(resourcePath);
response.setContentType(mimeType);
// 给http响应设置响应头 Content-Disposition
// 针对不同的浏览器对于下载的编码方式是不一样的
// Content-Disposition 是指定下载的数据的展示形式 , 如果attachment 则使用文件下载方式
if(request.getHeader("User-Agent").contains("Firefox")){
// 火狐 Base64编码
}else {
// 其他(主流ie/chrome)使用URL编码操作
response.setHeader("Content-Disposition", "attachment; filename=" +
URLEncoder.encode(fileName, "UTF-8"));
}
// 读取数据io流
InputStream resourceAsStream = servletContext.getResourceAsStream(resourcePath);
// 通过输出流输出
ServletOutputStream outputStream = response.getOutputStream();
// 通过IO工具类将读取到的文件输出
IOUtils.copy(resourceAsStream,outputStream);
}
}