使用Fileupload完成文件的上传下载
使用Fileupload完成文件的上传下载
为什么需要进行文件上传下载?
因为需要让用户能够访问服务器上的文件资源
引入jar包

文件上传
注意事项
- form表单的提交方式必须为post(因为get能够提交的数据量太小)
- form表单的 enctype属性必须为:"multipart/form-data",以二进制方式传输表单数据
- 需要提交的文件需要设置input的属性为file,必须设置name属性,否则无法被提交
编写一个简单的文件上传jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<base href="<%=request.getContextPath() + "/"%>">
</head>
<body>
<form action="upload/demo" enctype="multipart/form-data" method="post">
<p>
姓名:<input type="text" name="sname" />
</p>
<p>
年龄:<input type="number" name="age" />
</p>
<p>
请你上传你的头像:<input type="file" name="photo" /> <br>
<span style="color: red">${requestScope.errorMsg}</span>
</p>
<p>
<input type="submit" value="提交">
</p>
</form>
</body>
</html>
编写Servlet
Student类用于封装数据,后期展示用到
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student implements Serializable {
private Integer sid;
private String sname;
private Integer age;
private String fileName;
private String fileType;
}
Servlet处理文件上传
package com.oa.servlet;
import com.oa.entity.Student;
import com.oa.service.StudentService;
import com.oa.service.impl.StudentServiceImpl;
import org.apache.commons.fileupload.FileItem;
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.File;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
@WebServlet("/upload/demo")
public class UploadDemoServlet extends HttpServlet {
private StudentService studentService = new StudentServiceImpl();
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
// 定义一个学生实体的属性
String sname = "";
int age = 0;
String realFilename = "";
String fileType = "";
try {
// 生产FileItem的工厂类
DiskFileItemFactory factory = new DiskFileItemFactory();
// 实现上传操作的类
ServletFileUpload servletFileUpload = new ServletFileUpload(factory);
// 设置headerEncoding为UTF-8。这样可以解决上传的文件中文名问题
servletFileUpload.setHeaderEncoding("utf-8");
// servletFileUpload.setFileSizeMax(1024 * 20);// 设置文件最大上传大小为20k,如果超过直接抛出异常
// 获得到所有的表单项
List<FileItem> list = servletFileUpload.parseRequest(req);
// 遍历所有的表单项
for (FileItem fileItem : list) {
// 不是一个表单字段,表示为一个文件
if(!fileItem.isFormField()) {
// 判断文件格式
String filename = fileItem.getName();
fileType = filename.substring(filename.lastIndexOf("."));
if (!(".jpg".equals(fileType) || ".png".equals(fileType) || ".gif".equals(fileType))) {
req.setAttribute("errorMsg","文件格式不正确");
req.getRequestDispatcher("/fileuploadDemo.jsp").forward(req, resp);
return;
}
// 判断文件大小是否大于50k,这里的单位是字节
if (fileItem.getSize() > (1024 * 50)) {
req.setAttribute("errorMsg","图片大小最大为50k");
req.getRequestDispatcher("/fileuploadDemo.jsp").forward(req, resp);
return;
}
// 获得服务器的部署路径下的/imgs目录
String servletPath = this.getServletContext().getRealPath("/imgs");
File imgsDir = new File(servletPath);
// 如果文件夹不存在,就创建
if(!imgsDir.exists()) {
imgsDir.mkdirs();
}
// 最后存储在服务器上的文件名
realFilename = UUID.randomUUID().toString() + fileType;
// 写入到服务器中
fileItem.write(new File(imgsDir, realFilename));
}
// 这个时候就代表是字段
else {
if ("sname".equals(fileItem.getFieldName())){
// 这里以为UTF-8的格式获取数据
sname = fileItem.getString("utf-8");
}
if ("age".equals(fileItem.getFieldName())) {
age = Integer.parseInt(fileItem.getString());
}
}
}
// 封装Student对象存入数据库
Student student = new Student(null, sname, age, realFilename, fileType);
studentService.save(student);
} catch (Exception e) {
e.printStackTrace();
}
}
}
文件上传后可以在服务器的部署目录中看到一个imgs的目录,其中就是上传的图片

文件上传会遇到的一些问题解析
- 接收到的文件为中文名称时乱码
第1种解决方案:request.setCharacterEncoding("UTF-8");
第2种解决方案:
ServletFileUpload servletFileUpload = new ServletFileUpload(factory);
servletFileUpload.setHeaderEncoding("utf-8");
- 接收普通文本字段数据时发生乱码
// FileItem在获取数据时,指定编码
fileItem.getString("utf-8");
- 限定文件上传的格式(不完善,使用cpdetector插件可以精确判断)
// 先获取到文件的名称
String filename = fileItem.getName();
// 获取到文件的后缀
fileType = filename.substring(filename.lastIndexOf("."));
// 判断后缀
if (!(".jpg".equals(fileType)){}
- 限定文件上传的大小
// 第一种方式,如果超出大小会直接抛出异常(不推荐)
servletFileUpload.setFileSizeMax(1024 * 20);// 设置文件最大上传大小为20k
// 第二种方式
if (fileItem.getSize() > (1024 * 50)) {
req.setAttribute("errorMsg","图片大小最大为50k");
req.getRequestDispatcher("/fileuploadDemo.jsp").forward(req, resp);
return;
}
- 指定不到服务器的路径
// 使用getReal获取服务器的绝对路径,这里是获取部署路径下的下一级目录imgs
this.getServletContext().getRealPath("/imgs");
File imgsDir = new File(servletPath);
- 指定的文件目录不存在
// 如果文件夹不存在,就创建
if(!imgsDir.exists()) {
imgsDir.mkdirs();
}
- 文件名重复如何解决?
// 使用UUID + 文件后缀的方式
String realFileName = UUID.randomUUID().toString() + fileType;
文件下载
编写一个jsp文件用于student表数据的展示
- (这个表在前面文件上传的时候可以看到JavaBean)
- 这个数据写个Servlet解决就可以了
<body>
<table border="1px red solid" cellspacing="0" cellpadding="2px">
<thead>
<tr>
<th>学号</th>
<th>姓名</th>
<th>年龄</th>
<th>头像图片名称</th>
<th>图片格式</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<%-- 这里放你自己的数据 --%>
<c:forEach items="${requestScope.pageInfo.list}" var="student">
<tr>
<td>${student.sid}</td>
<td>${student.sname}</td>
<td>${student.age}</td>
<td><img width="160px" src="imgs/${student.fileName}" alt="" /></td>
<td>${student.fileType}</td>
<td><a href="download/demo?fileName=${student.fileName}&fileType=${student.fileType}">下载头像图片</a></td>
</tr>
</c:forEach>
</tbody>
</table>
</body>
编写Servlet完成文件下载功能
import org.apache.commons.io.IOUtils;
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.File;
import java.io.FileInputStream;
import java.io.IOException;
@WebServlet("/download/demo")
public class DownLoadServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取需要下载的文件名及其类型
String filename = req.getParameter("fileName");
String fileType = req.getParameter("fileType");
// 设置响应头,文件下载名称
resp.setHeader("Content-Disposition", "attachment; filename=" + filename);
// 设置响应的格式
resp.setContentType(fileType);
// 获取当前文件在服务器中的路径
String realPath = this.getServletContext().getRealPath("/imgs");
File file = new File(realPath, filename);
if (file.exists()) {
// 获得该文件的输入流
FileInputStream fis = new FileInputStream(file);
// 相应给客户端
IOUtils.copy(fis, resp.getOutputStream());
// 关闭资源
fis.close();
}
}
}
使用Fileupload完成文件的上传下载的更多相关文章
- JAVAWEB之文件的上传下载
文件上传下载 文件上传: 本篇文章使用的文件上传的例子使用的都是原生技术,servelt+jdbc+fileupload插件,这也是笔者的习惯,当接触到某些从未接触过的东西时,总是喜欢用最原始的东西将 ...
- 在Window的IIS中创建FTP的Site并用C#进行文件的上传下载
文件传输协议 (FTP) 是一个标准协议,可用来通过 Internet 将文件从一台计算机移到另一台计算机. 这些文件存储在运行 FTP 服务器软件的服务器计算机上. 然后,远程计算机可以使用 FTP ...
- 创建FTP的Site并用C#进行文件的上传下载
创建FTP的Site并用C#进行文件的上传下载 文件传输协议 (FTP) 是一个标准协议,可用来通过 Internet 将文件从一台计算机移到另一台计算机. 这些文件存储在运行 FTP 服务器软件的服 ...
- linux链接及文件互相上传下载
若排版紊乱可查看我的个人博客原文地址 基本操作 本篇博客主要介绍如何去链接远程的linux主机及如何实现本地与远程主机之间文件的上传下载操作,下面的linux系统是CentOS6.6 链接远程linu ...
- Spring实现文件的上传下载
背景:之前一直做的是数据库的增删改查工作,对于文件的上传下载比较排斥,今天研究了下具体的实现,发现其实是很简单.此处不仅要实现单文件的上传,还要实现多文件的上传. 单文件的下载知道了,多文件的下载呢? ...
- SocketIo+SpringMvc实现文件的上传下载
SocketIo+SpringMvc实现文件的上传下载 socketIo不仅可以用来做聊天工具,也可以实现局域网(当然你如果有外网也可用外网)内实现文件的上传和下载,下面是代码的效果演示: GIT地址 ...
- SSM框架之中如何进行文件的上传下载
SSM框架的整合请看我之前的博客:http://www.cnblogs.com/1314wamm/p/6834266.html 现在我们先看如何编写文件的上传下载:你先看你的pom.xml中是否有文件 ...
- python使用ftplib模块实现FTP文件的上传下载
python已经默认安装了ftplib模块,用其中的FTP类可以实现FTP文件的上传下载 FTP文件上传下载 # coding:utf8 from ftplib import FTP def uplo ...
- php文件夹上传下载控件分享
用过浏览器的开发人员都对大文件上传与下载比较困扰,之前遇到了一个php文件夹上传下载的问题,无奈之下自己开发了一套文件上传控件,在这里分享一下.希望能对你有所帮助. 以下是实例的部分脚本文件 这里我先 ...
随机推荐
- Jrebel、IDEA的激活与Springloaded使用
又有很长一段时间没写了,这次这篇随笔主要是分享下Jrebel与IDEA的激活方法以及推荐下Jrebel的替代工具Springloaded. 先来说下Jrebel的激活方法吧,之前有同事遇到了Jrebe ...
- CentOS安装ffmpeg+h264
CentOS安装ffmpeg+h264 前言 坑!坑!坑! 全是坑. 本文安装系统环境为CentOS7.2.我这里提供安装所需的四个源码包,均需要编译安装.所有组件最好都安装最新的稳定版,或者下载使用 ...
- 用VSCode终端实现重定向比较程序输出和正确输出
在刷 OJ 题目或者进行编程考试或比赛时,经常需要对编写好的程序进行测试,即运行编写好的程序,输入样例输入或者自己编写的输入数据,查看程序输出结果和样例输出或者正确输出是否一致.这种方法有很多弊端,当 ...
- 根据所处位置提取单元格内容的函数(left、right、mid)和查找字符串位于单元格内容第几位的函数(find)
1.从左到右提取:left(value,num_chars) 注释:value为操纵单元格,num_chars表示截取的字符的数量 2.从右往左提取:right(value,num_chars) 注释 ...
- 用 .SqlSugar ORM 来实现报表功能 .NET CORE /.NET
架框介绍 SqlSugar是一款.NET老牌ORM 并且也是 新手基数比较多的ORM(因为上手容易),SqlSugar之所以能一直更新到现在,还是要感谢SqlSugar的忠实用户,随着我的技术越来越好 ...
- 10、基本数据类型(set)
10.1.集合: 1.集合元素用大括号括起来,用逗号分割每个元素 2.集合的特点: (1)集合元素的数据类型只能是不可变数据类型,"列表"."字典"." ...
- Gym 101334E dp
分析: 这一题给出的遍历的点的序列,不是树的中序遍历,前序遍历,只要遇到一个节点就打印一个节点.关键点就在,这个序列的首字母和尾字母一定要相同,因为最终都会回到根节点,那么每一个子树也一样. 状态: ...
- 自然语言处理(NLP)——简介
自然语言处理(NLP Natural Language Processing)是一种专业分析人类语言的人工智能.就是在机器语⾔和⼈类语言之间沟通的桥梁,以实现人机交流的目的. 在人工智能出现之前,机器 ...
- AcWing 829. 模拟队列
实现一个队列,队列初始为空,支持四种操作: (1) "push x" – 向队尾插入一个数x: (2) "pop" – 从队头弹出一个数: (3) " ...
- 滑动窗口通用解leetcode字符串匹配问题
滑动窗口,这玩意解决一些字符串匹配的题目是真的挺好用的,虽然本质还是双指针. 思路: 1.维护一个窗口,不断的向右边移动 2.满足要求后,移动左边,当不满足时,跳出. 3.重复1,2.得出答案. 下面 ...