基于servlet实现文件上传下载

前言
在Servlet2.5中,我们要实现文件上传功能时,一般都需要借助第三方开源组件,例如Apache的commons-fileupload组件,在Servlet3.0中提供了对文件上传的原生支持,我们不需要借助任何第三方上传组件,直接使用Servlet3.0提供的API就能够实现文件上传功能了。
文件域和表单的enctype属性
一、关于HTML 标签的 enctype 属性
application/x-www-form-urlencoded:在发送前编码所有字符(默认)
multipart/form-data: 不对字符编码,或在使用包含文件上传控件的表单时,必须使用该值。
text/plain:空格转换为 “+” 加号,但不对特殊字符编码。
二、enctype:规定了form表单在发送到服务器时候编码方式,有如下的三个值。
1、application/x-www-form-urlencoded。默认的编码方式。但是在用文本的传输和MP3等大型文件的时候,使用这种编码就显得 效率低下。
2、multipart/form-data 。 指定传输数据为二进制类型,比如图片、mp3、文件。
3、text/plain。纯文体的传输。空格转换为 “+” 加号,但不对特殊字符编码。

简单的说,在我们要进行文件上传时应该设置表单组件的enctype属性为multipart/form-data,已二进制的方式提交表单,从而可以提交上传各种类型的文件

<fieldset>
<legend>上传单个文件</legend>
<form action="upload" method="post" enctype="multipart/form-data">
        上传文件: <input type="file" name="myFile"><br>
<input type="submit" value="上传">
</form>
</fieldset>
<fieldset>
<legend>上传多个文件</legend>
<form action="upload" method="post" enctype="multipart/form-data">
      上传文件: <input type="file" name="myFile"><br>
      上传文件: <input type="file" name="myFile"><br>
<input type="submit" value="上传">
</form>
</fieldset>

@MultipartConfig注解和Part对象
Servlet3.0 提供了@MultipartConfig注解,让我们的servlet能够接受来自客户端提交的二进制数据,通过request对象的getPart/getParts方法即可从请求中提取上传的文件信息

@WebServlet("/upload")
@MultipartConfig
public class UploadServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Collection<Part> partList = req.getParts(); //获取当前表单中提交的所有文件,返回一个集合
        Part part = req.getPart("name"); //根据文件域所对应的name提取单个文件
}
}

当获取了part对象后,可以利用part提供的api进一步获取文件的相关信息

Part part = req.getPart("myFile");
            String header = part.getHeader("content-disposition");//获取mime头信息
            String fileName = part.getSubmittedFileName(); //获取文件名
long size = part.getSize(); //获取文件大小
            String type = part.getContentType(); //获取文件类型
            System.out.println(fileName);
            System.out.println(size);
            System.out.println(type);

针对之前的HTML案例,我们可以编写一个用于接收一个或多个文件的上传的servlet

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.UUID;

@WebServlet("/upload")
@MultipartConfig
public class UploadServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Collection<Part> partList = req.getParts();
        req.setCharacterEncoding("utf-8");
        if(partList.size()==1){
            Part part = req.getPart("myFile");
            String header = part.getHeader("content-disposition");
            String fileName = part.getSubmittedFileName(); //获取文件名
            long size = part.getSize(); //获取文件大小
            String type = part.getContentType(); //获取文件类型
            System.out.println(fileName);
            System.out.println(size);
            System.out.println(type);
            String path = req.getServletContext().getRealPath("/upload")+File.separator+UUID.randomUUID()+fileName;
            part.write(path);
        }else{
            for (Part part : partList) {
                String fileName = part.getSubmittedFileName();
                String path = req.getServletContext().getRealPath("/upload") + File.separator + UUID.randomUUID() + fileName;
                part.write(path);
                req.getRequestDispatcher("/getFiles").forward(req,resp);
            }
        }
    }
}

知识点:
request.getServletContext(): 获取当前上下文/容器对象ServletContext.getRealPath(“path”): 返回上下文目录中某个文件/文件夹的完整路径UUID.randomUUID(): 根据UUID获取一个32位随机字符
文件下载
要实现下载非常简单,只需要向浏览器声明content-disposition标明attachment即可,如果不标识这个信息,浏览器会直接打开该文件(如果浏览器可以打开,如图片,文档等),如果打不开也会激活下载
大致思路就是,我们通过一个输入流,读取想要让客户端下载的文件字节,然后通过输出流写到客户端即可,基本的IO操作

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;
import java.io.InputStream;

@WebServlet("/down")
public class DownLoadServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
//        String fileName = new String(req.getParameter("fileName").getBytes("iso-8859-1"),"utf-8");
        String fileName =req.getParameter("fileName");
        System.out.println(fileName);
String path = req.getServletContext().getRealPath("/upload");
        File f= new File(path+File.separator+fileName);
        resp.setCharacterEncoding("utf-8");
        resp.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
        System.out.println(f);
        try{
            InputStream input = new FileInputStream(f);
            ServletOutputStream out = resp.getOutputStream();
            byte[] buffer = new byte[1024];
            int len =0;
            while((len=input.read(buffer))!=-1){
                out.write(buffer);
            }
            input.close();
            out.close();
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值