JavaWeb Servlet实现文件上传与下载功能实例

作者:CoderX(远离BUG) 时间:2023-06-16 16:41:27 

前言

在上网的时候我们常常遇到文件上传的情况,例如上传头像、上传资料等;当然除了上传,遇见下载的情况也很多,接下来看看我们 servlet 中怎么实现文件的上传和下载。

项目准备

idea:2020.1

jdk:1.8

tomcat:10

项目模板:java Enterprise–>Web Application

文件上传

文件上传涉及到前台页面的编写和后台服务器端代码的编写,前台发送文件,后台接收并保存文件,这才是一个完整的文件上传。

前台页面

在做文件上传的时候,会有一个上传文件的界面,首先我们需要一个表单,并且表单的请求方式为 POST;其次我们的 form 表单的 enctype 必须设为"multipart/form-data",即 enctype=“multipart/form-data”,意思是设置表单的类型为文件上传表单。默认情况下这个表单类型是 “application/x-www-form-urlencoded”, 不能用于文件上传。只有使用了multipart/form-data 才能完整地传递文件数据。

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>文件上传</title>
</head>
<body>
<!--文件上传
   1. 准备表单
   2.设置表单提交类型为POST method="POST"
   3.设置表单类型为文件上传表单 enctype="multipart/form-data"
   4.设置文件提交地址 action地址需要和后台servlet注解保持一致
   5.准备表单元素
   6.设置表单元素的name属性值(否则后台无法接收数据)
-->
<form method="post" enctype="multipart/form-data" action="upLoadServlet">
   姓名:<input type="text" name="uname"><br>
   文件:<input type="file" name="myfile"><br>
   <!--button默认时提交类型 type="submit"-->
   <button>提交</button>
</form>

</body>
</html>

后台实现

使用注解 @MultipartConfig 将一个 Servlet 标识为支持文件上传。 Servlet 将 multipart/form-data 的 POST 请求封装成 Part,通过 Part 对上传的文件进行操作。

package formServlet;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.MultipartConfig;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.Part;

import java.io.IOException;

/*
* 文件上传
* 1.使用注解@MultipartConfig,将servlet标识为支持文件上传
* 2.servlet将muitipart/form-data的POST请求封装成part对象,通过part对文件上传进行操作
*
*/
@WebServlet("/upLoadServlet")
@MultipartConfig  //文件上传注解
public class UploadServlet extends HttpServlet {

@Override
   protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       System.out.println("文件上传");
       //设置请求编码格式
       req.setCharacterEncoding("UTF-8");
       //获取普通表单元素
       String uname=req.getParameter("uname");
       System.out.println("uname:"+uname);
       //获取part对象
       Part part=req.getPart("myfile");
       //通过part对象获得上传文件名
       String fileName = part.getSubmittedFileName();
       System.out.println("file:"+fileName);
       //得到文件存放路径
       String filePath = req.getServletContext().getRealPath("/");
       System.out.println("filePath:"+filePath);
       //上传文件到指定路径
       part.write(filePath+"/"+fileName);
   }
}

提交表单后查看控制台打印结果

文件上传
uname:张三
file:exception.jpg
filePath:E:\bdqn\JavaWeb\servlet\out\artifacts\servlet_war_exploded\

文件下载

文件下载,即将服务器上的资源下载(拷贝)到本地,我们可以通过两种方式下载。第一种是通过超链接本身的特性来下载;第二种是通过代码下载。

资源准备

在web目录下新建文件夹存放下载资源,通过tomcat配置添加Deployment到服务器中

JavaWeb Servlet实现文件上传与下载功能实例

JavaWeb Servlet实现文件上传与下载功能实例

超链接下载

当我们在 HTML 或 JSP 页面中使用a标签时,原意是希望能够进行跳转,但当超链接遇到浏览器不识别的资源时会自动下载;当遇见浏览器能够直接显示的资源,浏览器就会默认显示出来,比如 txt、png、jpg 等。当然我们也可以通过 download 属性规定浏览器进行下载。但有些浏览器并不支持。

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>文件下载</title>
</head>
<body>
<!--
超链接下载
       1.当时用超链接(a标签)时,如果遇到浏览器能够识别的内容,会显示内容,而不会进行下载.
        指定download属性进行下载;

2.如果遇到浏览器不能识别的内容,会进行下载
-->
<!--浏览器能够识别的资源,显示内容-->
<a href="download/1.txt">文本文件</a>
<a href="download/retrun.jpg">图片文件</a>
<!--压缩文件是浏览器不能识别的资源,进行下载-->
<a href="download/1.zip">压缩文件</a>
<!--浏览器能够识别的资源,设置download属性,进行下载-->
<!--download="文件名.后缀名",不设置文件名和后缀名会默认服务器中的文件属性-->
<a href="download/1.txt" download>文本文件下载</a>
<a href="download/retrun.jpg" download="re.png">图片文件下载</a>

</body>
</html>

download 属性可以不写任何信息,会自动使用默认文件名。如果设置了download属性的值,则使用设置的值做为文件名。当用户打开浏览器点击链接的时候就会直接下载文件。

后台实现下载

实现步骤

  1. 需要通过 response.setContentType 方法设置 Content-type 头字段的值, 为浏览器无法使用某种方式或激活某个程序来处理的 MIME 类型,例 如 &ldquo;application/octet-stream&rdquo; 或 &ldquo;application/x-msdownload&rdquo; 等。

  2. 需要通过 response.setHeader 方法设置 Content-Disposition 头的值 为 &ldquo;attachment;filename=文件名&rdquo;

  3. 读取下载文件,调用 response.getOutputStream 方法向客户端写入附件内容。

package formServlet;

import jakarta.servlet.ServletException;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

/**
* 文件下载
* 1. 需要通过 response.setContentType 方法设置 Content-type 头字段的值, 为浏览器无法使用某种方式或激活某个程序来处理的 MIME 类型,例 如 "application/octet-stream" 或 "application/x-msdownload" 等。
* 2. 需要通过 response.setHeader 方法设置 Content-Disposition 头的值 为 "attachment;filename=文件名"
* 3. 读取下载文件,调用 response.getOutputStream 方法向客户端写入附件内容。
*/
@WebServlet("/downloadServlet")
public class DownloadServlet extends HttpServlet {
   @Override
   protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       System.out.println("文件下载...");
       //设置请求编码格式
       req.setCharacterEncoding("UTF-8");
       resp.setContentType("text/html;charset=UTF-8");
       //获取参数(下载文件名)
       String fileName = req.getParameter("fileName");
       System.out.println(fileName);
       //参数非空判断 trim():去除字符串的前后空格
       if(fileName==null||"".equals(fileName.trim())){
           //参数为空,写入浏览器提示
           resp.getWriter().write("请输入要下载的文件名!");
           resp.getWriter().close();  //关闭流
           return; //退出当前
       }
       //得到文件存放路径
       String filePath=req.getServletContext().getRealPath("/download/");
       //通过路径得到file对象
       File file = new File(filePath + fileName);
       //判断文件对象是否存在并且是标准文件
       if(file.exists()&&file.isFile()){
           //设置响应类型(浏览器无法使用某种方式或激活某个程序来处理的 MIME 类型)
           resp.setContentType("application/x-msdownload");
           //设置响应头
           resp.setHeader("Context-Disposition","attachment;filename="+fileName);
           //得到file文件输入流
           FileInputStream fis = new FileInputStream(file);
           //得到字节输出流
           ServletOutputStream sos=resp.getOutputStream();
           //定义byte数组
           byte[] bytes=new byte[1024];
           //定义长度
           int len=fis.read(bytes);
           //循环输出
           while (len!=-1){
               sos.write(bytes,0,len);
           }
           //关闭资源 先打开的后关闭
           sos.close();
           fis.close();
       }else {
           resp.getWriter().write("文件不存在,请重试!");
           resp.getWriter().close();
       }
   }
}

来源:https://blog.csdn.net/qq_45925787/article/details/124421317

标签:servlet,上传,下载
0
投稿

猜你喜欢

  • android中webview控件和javascript交互实例

    2023-09-06 14:09:28
  • android Service基础(启动服务与绑定服务)

    2023-05-07 12:31:34
  • IntelliJ Idea常用11款插件(提高开发效率)

    2022-08-31 14:08:23
  • Java 常量与变量的区别详细介绍

    2023-03-09 13:30:48
  • SpringAOP切点函数实现原理详解

    2021-09-05 11:00:59
  • 基于mybatis plus实现数据源动态添加、删除、切换,自定义数据源的示例代码

    2021-08-20 20:07:46
  • IOS开发向右滑动返回前一个页面功能(demo)

    2021-09-23 04:30:11
  • 详解使用Spring3 实现用户登录以及权限认证

    2023-05-07 03:59:12
  • Android编程之SMS读取短信并保存到SQLite的方法

    2022-01-30 18:02:45
  • Java 实战项目之仓库管理系统的实现流程

    2021-10-05 09:14:07
  • Android实现的秒表计时器示例

    2023-04-26 11:32:56
  • C#根据前台传入实体名称实现动态查询数据

    2021-06-17 09:28:43
  • Android 仿今日头条评论时键盘自动弹出的效果(推荐)

    2022-07-24 15:00:45
  • MyBatisPlus代码生成器的使用示例

    2022-04-28 07:52:42
  • Spring实现动态切换多数据源的解决方案

    2023-05-21 13:07:15
  • Java多线程的临界资源问题解决方案

    2021-12-29 07:44:35
  • 一文搞懂Java ScheduledExecutorService的使用

    2022-11-22 14:23:35
  • SpringBoot项目中如何访问HTML页面

    2021-08-09 11:19:07
  • MapStruct处理Java中实体与模型间不匹配属性转换的方法

    2023-08-02 22:31:28
  • SpringCloud之熔断器Hystrix的实现

    2021-09-21 01:39:26
  • asp之家 软件编程 m.aspxhome.com