实现简单的文件上传和下载(Servlet)

文件上传

1.前端代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>上传和下载</title>
</head>
<body>
   //method="post" 提交方式 enctype="multipart/form-data" 编码类型 action="fileUpload" 提交的地址 不加 / 
  <form method="post" enctype="multipart/form-data" action="fileUpload">
     上传文件: <input type="file" name="uploadFile"><br>//上传文件,所以type是file 
      <button>确定</button>//form表单中的button按钮默认是提交按钮
  </form>
</body>
</html>

2.服务端

@WebServlet("/fileUpload") //访问地址  fomr表单的 action="fileUpload" 保持一致 
@MultipartConfig //必须加!!!
public class Upload extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");//设置编码格式 因为文件名是中文
        Part part=request.getPart("uploadFile"); //获取一个 Part 对象
        String fname=part.getSubmittedFileName(); //获取上传的文件名包括后缀
        String fpath=getServletContext().getRealPath("/"); //获取当代目录的根目录
        part.write(fpath+"/"+fname); //保存上传的文件
        System.out.println("上传路径"+fpath); //打印保存上传文件的路径
    }
}

同时上传多个文件

html

给input 设置一个属性 multiple=“multiple”

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>上传和下载</title>
</head>
<body>
  <form method="post" multiple="multiple" enctype="multipart/form-data" action="fileUpload">
     上传文件: <input type="file" multiple="multiple" name="uploadFile"><br>
      <button>确定</button>
  </form>
</body>
</html>

java

@WebServlet("/fileUpload")
@MultipartConfig
public class Upload extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       request.setCharacterEncoding("utf-8");
       Collection<Part> pts= request.getParts();
       for (Part part:pts){
        String fname=part.getSubmittedFileName();
        String fpath=getServletContext().getRealPath("/");
        part.write(fpath+"/"+fname);
        System.out.println("上传路径"+fpath);
       }
       //下面写的是单个文件上传
//        Part part=request.getPart("uploadFile");
//        String fname=part.getSubmittedFileName();
//        String fpath=getServletContext().getRealPath("/");
//        part.write(fpath+"/"+fname);
//        System.out.println("上传路径"+fpath);
    }
    public void logg(Object o){
        System.out.println("*********  "+o);
    }
}

注意(上传)!

1.服务端必须加注解

@MultipartConfig

2.设置编码格式

request.setCharacterEncoding("utf-8");

3.form表单的 编码类型

 <form method="post" enctype="multipart/form-data" action="fileUpload">

4.form表单的 的访问地址与服务端保存一致
form表单 不加 / 号

 @WebServlet("/fileUpload")

 <form method="post" enctype="multipart/form-data" action="fileUpload">

文件下载

1.a标签直接下载

<%--
  Created by IntelliJ IDEA.
  User: lzz
  Date: 2021/1/6
  Time: 11:34
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>文件下载</title>
  </head>
  <body>
  //a标签下载   注意要加download 可以直接写 download
  <a href="Download/mysql.zip" download>超链接下载(zip压缩文件)</a><br>
  <a href="Download/捕获.PNG" download="图片">超链接下载(PNG图片文件)</a><br>
  <a href="Download/新建文本文档.txt" download>超链接下载(txt文本文件)</a><br>
   //后台下载
  <form method="get" action="downloadf"
  >
    文件名:<input name="fileName" type="text">
    <button>下载</button>
  </form>
  </body>
</html>

*1.后台下载


@WebServlet("/downloadf")
public class Download extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");//设置编码格式
        String fileName=req.getParameter("fileName");//获取下载的文件名
        if ("".equals(fileName.trim())||fileName==null){// 空判断
            resp.getWriter().write("不可为空");
            resp.getWriter().close();//关闭流
            return;
        }
        resp.setHeader("content-type","text/html;charset=utf-8");//设置响应头
        //resp.setContentType("text/html;charset=utf-8"); 作用同上
        ServletContext servletContext = this.getServletContext();
        String filepath = servletContext.getRealPath("/download/" );//或去下载的地址
        File file=new File((filepath+fileName).trim());
        
        if (file.isFile()&&file.exists()){//判断文件是否存在
            resp.setContentType("application/x-msdownload");//设置响应类型(浏览器无法使用某个程序或某种方式来处理 MIME类型)
            resp.setHeader("Content-Disposition", "attachment;fileName="+fileName);//设置下载的文件名称
            try (FileInputStream in=new FileInputStream(file);
                 ServletOutputStream out=resp.getOutputStream())
            {
                byte [] buf=new byte[1024];
                int i=0;
                while ((i=in.read(buf))!=-1){
                    out.write(buf,0,i);
                }
            }catch (IOException e){
                logg("错误信息:"+e.getMessage());
            }
        }else{
            resp.getWriter().write("文件不存在或者文件名输入有误(包含后缀如.jpn)");
            resp.getWriter().close();
        }


    }
    public void logg(Object o){
        System.out.println(o);
    }
}

下载文件时,form表单提交文件名称是中文时出现乱码(巨坑)

我一开始打印从表单的获取要下载文件的名称时,突然发现是乱码,然后后面百度了好久,终于解决了,结果发现

logg(file.isFile()+"--"+file.exists());//打印结果 false--false

我又去复制打印的完整文件地址,去找,发现又可以找到。当时就人傻了。。。。
然后突然想起,IDEA打印中文时一开始就是乱码,感觉人蠢了。。。。

req.setCharacterEncoding("UTF-8"); //解决了。。。。。。

然后百度一波,修改IDEA打印的编码格式。就可以了。

resp.setHeader(“Content-Disposition”, “attachment;fileName=”+fileName);中文文件名乱码

看下图,要么是乱码,要么是 ____
解决方法:

fileName=new String(fileName.getBytes("utf-8"),"ISO-8859-1");

在这里插入图片描述

完整的代码

package com.xxxx.servlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
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("/downloadf")
public class Download extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        String fileName=req.getParameter("fileName");
        if ("".equals(fileName.trim())||fileName==null) {
            resp.getWriter().write("不可为空");
            resp.getWriter().close();//关闭流
            return;
        }
        resp.setHeader("content-type","text/html;charset=utf-8");
        ServletContext servletContext = this.getServletContext();
        String filepath = servletContext.getRealPath("/download/" );
        File file=new File((filepath+fileName).trim());
        if (file.isFile()&&file.exists()){
            resp.setContentType("application/x-msdownload");
            fileName=new String(fileName.getBytes("utf-8"),"ISO-8859-1");
            resp.setHeader("Content-Disposition", "attachment;fileName="+fileName);
            try (FileInputStream in=new FileInputStream(file);
                 ServletOutputStream out=resp.getOutputStream())
            {
                byte [] buf=new byte[1024];
                int i=0;
                while ((i=in.read(buf))!=-1){
                    out.write(buf,0,i);
                }
            }catch (IOException e){
                logg("错误信息:"+e.getMessage());
            }
        }else{
            resp.getWriter().write("文件不存在或者文件名输入有误(包含后缀如.jpn)");
            resp.getWriter().close();
        }


    }
    public void logg(Object o){
        System.out.println("*********  "+o);
    }
}

<%--
  Created by IntelliJ IDEA.
  User: lzz
  Date: 2021/1/6
  Time: 11:34
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>文件下载</title>
  </head>
  <body>
  <a href="Download/mysql.zip" download>超链接下载(zip压缩文件)</a><br>
  <a href="Download/捕获.PNG" download>超链接下载(PNG图片文件)</a><br>
  <a href="Download/新建文本文档.txt" download>超链接下载(txt文本文件)</a><br>

  <form method="get" action="downloadf"
  >
    文件名:<input name="fileName" type="text">
    <button>下载</button>
  </form>
  </body>
</html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是实现Servlet文件上传下载的设计: 首先是文件上传: 1. 在web.xml文件中配置文件上传Servlet,例如: ```xml <servlet> <servlet-name>UploadServlet</servlet-name> <servlet-class>com.example.UploadServlet</servlet-class> <multipart-config> <location>/tmp</location> <max-file-size>2097152</max-file-size> <max-request-size>4194304</max-request-size> <file-size-threshold>1048576</file-size-threshold> </multipart-config> </servlet> <servlet-mapping> <servlet-name>UploadServlet</servlet-name> <url-pattern>/upload</url-pattern> </servlet-mapping> ``` 2. 编写UploadServlet类,处理文件上传请求。在doPost方法中,使用HttpServletRequest的getPart方法获取上传的文件,然后将其保存到服务器的某个目录中,例如: ```java protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取上传的文件 Part filePart = request.getPart("file"); String fileName = getFileName(filePart); InputStream fileContent = filePart.getInputStream(); // 将文件保存到服务器的某个目录中 String uploadPath = getServletContext().getRealPath("/uploads"); File uploadDir = new File(uploadPath); if (!uploadDir.exists()) { uploadDir.mkdir(); } File file = new File(uploadPath + File.separator + fileName); OutputStream outputStream = new FileOutputStream(file); byte[] buffer = new byte[1024]; int bytesRead = 0; while ((bytesRead = fileContent.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } outputStream.close(); fileContent.close(); // 返回上传结果 response.getWriter().println("File uploaded successfully."); } private String getFileName(Part filePart) { String contentDisposition = filePart.getHeader("content-disposition"); String[] elements = contentDisposition.split(";"); for (String element : elements) { if (element.trim().startsWith("filename")) { return element.substring(element.indexOf("=") + 1).trim().replace("\"", ""); } } return null; } ``` 以上就是文件上传的设计,上传的文件将保存到服务器的uploads目录中。接下来是文件下载: 1. 编写DownloadServlet类,处理文件下载请求。在doGet方法中,根据请求参数获取要下载文件名,然后将其读入到InputStream中,最后将其写入到OutputStream中,例如: ```java protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取要下载文件名 String fileName = request.getParameter("file"); // 将文件读入到InputStream中 String filePath = getServletContext().getRealPath("/uploads") + File.separator + fileName; File file = new File(filePath); InputStream inputStream = new FileInputStream(file); // 将文件写入到OutputStream中 OutputStream outputStream = response.getOutputStream(); byte[] buffer = new byte[4096]; int bytesRead = -1; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } inputStream.close(); outputStream.close(); } ``` 以上就是文件下载的设计,下载文件将从服务器的uploads目录中读取并下载。 需要注意的是,在上传和下载文件时,需要考虑文件的大小,避免上传和下载过大的文件造成系统负载过高。同时,需要保证文件上传下载的安全性,避免用户上传和下载恶意文件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值