使用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完成文件的上传下载的更多相关文章

  1. JAVAWEB之文件的上传下载

    文件上传下载 文件上传: 本篇文章使用的文件上传的例子使用的都是原生技术,servelt+jdbc+fileupload插件,这也是笔者的习惯,当接触到某些从未接触过的东西时,总是喜欢用最原始的东西将 ...

  2. 在Window的IIS中创建FTP的Site并用C#进行文件的上传下载

    文件传输协议 (FTP) 是一个标准协议,可用来通过 Internet 将文件从一台计算机移到另一台计算机. 这些文件存储在运行 FTP 服务器软件的服务器计算机上. 然后,远程计算机可以使用 FTP ...

  3. 创建FTP的Site并用C#进行文件的上传下载

    创建FTP的Site并用C#进行文件的上传下载 文件传输协议 (FTP) 是一个标准协议,可用来通过 Internet 将文件从一台计算机移到另一台计算机. 这些文件存储在运行 FTP 服务器软件的服 ...

  4. linux链接及文件互相上传下载

    若排版紊乱可查看我的个人博客原文地址 基本操作 本篇博客主要介绍如何去链接远程的linux主机及如何实现本地与远程主机之间文件的上传下载操作,下面的linux系统是CentOS6.6 链接远程linu ...

  5. Spring实现文件的上传下载

    背景:之前一直做的是数据库的增删改查工作,对于文件的上传下载比较排斥,今天研究了下具体的实现,发现其实是很简单.此处不仅要实现单文件的上传,还要实现多文件的上传. 单文件的下载知道了,多文件的下载呢? ...

  6. SocketIo+SpringMvc实现文件的上传下载

    SocketIo+SpringMvc实现文件的上传下载 socketIo不仅可以用来做聊天工具,也可以实现局域网(当然你如果有外网也可用外网)内实现文件的上传和下载,下面是代码的效果演示: GIT地址 ...

  7. SSM框架之中如何进行文件的上传下载

    SSM框架的整合请看我之前的博客:http://www.cnblogs.com/1314wamm/p/6834266.html 现在我们先看如何编写文件的上传下载:你先看你的pom.xml中是否有文件 ...

  8. python使用ftplib模块实现FTP文件的上传下载

    python已经默认安装了ftplib模块,用其中的FTP类可以实现FTP文件的上传下载 FTP文件上传下载 # coding:utf8 from ftplib import FTP def uplo ...

  9. php文件夹上传下载控件分享

    用过浏览器的开发人员都对大文件上传与下载比较困扰,之前遇到了一个php文件夹上传下载的问题,无奈之下自己开发了一套文件上传控件,在这里分享一下.希望能对你有所帮助. 以下是实例的部分脚本文件 这里我先 ...

随机推荐

  1. 免费获取思维导图Mindmaster会员教程

    免费获取思维导图Mindmaster会员教程 步骤一.下载安装 搜索亿图官方网页,下载安装免费版Mindmaster思维导图. 步骤二.点击登录 打开Mindmaster思维导图,点击登录,可以使用微 ...

  2. 对ES6中类class以及实例对象、原型对象、原型链之间关系的详细总结

    1. 类 ES6 中新增加了类的概念,可以使用 class 关键字声明一个类,之后用这个类来实例化对象.即类的用途:实例化对象. // 创建一个Person类 class Person { } // ...

  3. mysql字符集utf8和utf8mb4区别

    1.起因 公司游戏项目上线第一天,出现单个区服异常宕机的问题,根据日志排查下来,连接数据的时候报错,后面排查是因为有玩家插入Emoji 等表情导致无法存储如数据库,数据库字符集编码为utf8,后续改成 ...

  4. Gitlab触发jenkins并获取项目post参数

    jenkins -- Generic Webhook Trigger插件 此插件是git webhook的高阶应用,安装后会暴露出来一个公共API,GWT插件接收到 JSON 或 XML 的 HTTP ...

  5. vue elementui table 内按钮跳转页面

    vue : <el-table-column label="操作" v-if="isColumOperate"> <template slot ...

  6. jquery 选择器 模糊匹配

    根据name值匹配 1.查询前缀为aa的数据 $("div[name^='aa']"); 2.查询后缀为aa的所有div的jquery对象 $("div[name$='a ...

  7. 超详细的原生JavaScript轮播图(幻灯片)的制作

    本次轮播图的制作主要分为3个部分,分别是:设置定时器自动轮播:点击左右切换按钮轮播:下方点击按钮轮播.具体实现步骤如下: (效果图) html部分代码如下: <div class="s ...

  8. Docker:Linux离线安装docker-17.03.2-ce,配置开机自启

    1. 准备docker离线包 docker官方离线包下载地址 下载需要安装的docker版本,我此次下载的是:docker-17.03.2-ce.tgz 2. 准备docker.service 系统配 ...

  9. docker进入容器所在虚拟机的指令

    sudo docker inspect -f {{.State.Pid}} 44fc0f0582d9 在拿到该进程PID之后我们就可以使用nsenter命令访问该容器了. $ sudo nsenter ...

  10. 深入浅出图神经网络 第6章 GCN的性质 读书笔记

    第6章 GCN的性质 第5章最后讲到GCN结束的有些匆忙,作为GNN最经典的模型,其有很多性质需要我们去理解. 6.1 GCN与CNN的区别与联系 CNN卷积卷的是矩阵某个区域内的值,图卷积在空域视角 ...