使用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. 『无为则无心』Python基础 — 9、Python字符串的编码与转义

    目录 1.查看变量类型 2.转义字符 (1)转义字符说明 (2)示例 (3)常用转义字符对照表 3.字符编码 (1)字符编码介绍 (2)Python中的字符编码 (3)编码格式应用于不同场景 提示:上 ...

  2. 开源版本的 uTools。可支持 uTools 所有插件生态

    话不多说,先放上截图和仓库地址: 代码仓库:github 故事背景 网络抓包 之前公司内部因为开发需要,需要和后端进行接口联调,测试环境的时候,经常会涉及到一些状态改变要看交互样式的问题.比如测试需要 ...

  3. 解决 Golnag Gin框架跨域

    package main import ( "github.com/gin-gonic/gin" "awesomeProject/app/app_routers" ...

  4. Apache Hudi在Hopworks机器学习的应用

    Hopsworks特征存储库统一了在线和批处理应用程序的特征访问而屏蔽了双数据库系统的复杂性.我们构建了一个可靠且高性能的服务,以将特征物化到在线特征存储库,不仅仅保证低延迟访问,而且还保证在服务时间 ...

  5. Kubernetes通过downwardAPI传递元数据

    应用往往需要获取所运行环境的一些信息,包括应用自身以及集群中其他组件的信息.Kubernetes可以通过环境变量以及DNS进行服务发现,但其他信息如何处理呢?下面将介绍特定pod和容器元数据如何被传递 ...

  6. 如何使用「mkvtoolnix」和「GoldWave」仅保留视频中左、右声道的其中一个声道?

    为什么要这样做? 我手上有一部电视剧的视频文件(.rmvb),每个视频文件都是"国/粤双语"的,与其他双语视频的两种语言的音频保存在两个音轨上不同,我这里的视频文件的双语是分别保存 ...

  7. Linux系统下安装NodeJS

    下载NodeJS二进制压缩包 去NodeJS官网https://nodejs.org/zh-cn/,下载二进制压缩包,进入下载页面之后你将看到很多下载选项: 源码不包含bin目录,不是可运行的应用程序 ...

  8. DRF之权限和频率限制

    一.权限 权限可以限制用户对视图的访问和对具体数据对象的访问. 在执行视图的dispatch方法前,会先进行视图访问权限的判断 在通过get_object获取对象时,会进行模型对象访问权限的判断 源码 ...

  9. Centos-Springboot项目jar包自启动

    CentOS环境下部署Springboot项目的jar包开机自启动. 部署环境 Centos 7.5 Springboot 2.1.x 操作步骤 修改pom 在pom.xml文件中<plugin ...

  10. android开发相关知识笔记

    1.xpage页面打开: openPage(TestFragment.class) openPage("标识") // 页面打开等待结果返回: openPageForResult( ...