0730.笔记.Servlet.文件上传下载

一、文件上传

想要进行文件的上传下载,需要先在表单中设置 enctype = "multipart/form-data"

 <%-- 此处需要声明enctype属性说明文件为多段传输--%>
<form action="/0729_JSPTest/inputPhoto" method="post" enctype="multipart/form-data">
    请输入用户名:<input type="text" name="username">
    <br>
    <input type="file" name="photo" value="请上传头像">
    <br>
    <input type="submit" value="上传~">
</form>

然后为IDEA添加jar包依赖

在WEB-INF下新建lib文件夹,将commons-fileupload.jar 、 commons-io.jar加入依赖

 编写ServletUpload类继承HttpServlet 并重写doPost方法

首先要判断请求头是否是多段数据,如果不是多段数据传输则无法实现文件上传

开始文件上传:

首先创建FileItemFactory工厂实现类

FileItemFactory fileItemFactory = new DiskFileItemFactory();

因为接收到的文件未解析,所以需要创建一个解析器

创建一个解析上传文件的工具类ServletFileUpload,有参构造参数为工厂对象

ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory);

因为接收到的文件如果是中文则会出现乱码,所以需要设置收到的上传文件的请求头的编码格式

servletFileUpload.setHeaderEncoding("utf-8");

因为要为浏览器回传提示,所以设置浏览器编码格式(在响应头中)

resp.setContentType("text/html;charset = utf-8");

因为表单提交的内容有多项,其中有普通表单项也有文件项,所以将收到的表单项存入List集合

解析器的.parseRequest方法解析上传的数据

List<FileItem> list = servletFileUpload.parseRequest(req);

遍历每个表单项目

for(FileItem fileItem : list)

{

        使用.isFormField判断是否是普通表单类型

        如果是普通的表单项

                打印表单name和value到服务器控制台

                在浏览器打印提示

        否则

        {

                是文件,则使用write方法下载到服务器中 

                fileItem.write(new File("下载的路径" + fileItem.getName()));

        }

}

完整代码:

package com.teen.JSPTest0729;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;

/**
 * @author teen
 * @create 2021/7/29 18:36
 */
public class FileInputServlet extends HttpServlet {


    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //判断上传的数据是否是多段数据
        if (ServletFileUpload.isMultipartContent(req))
        {
            //创建FileItemFactory工厂实现类
            FileItemFactory fileItemFactory = new DiskFileItemFactory();
            //创建一个用于解析上传文件的工具类ServletFileUpload
            ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory);
//            这里就是中文文件名处理的代码,setHeaderEncoding设置请求头编码格式
            servletFileUpload.setHeaderEncoding("utf-8");
            //设置浏览器格式为utf-8
            resp.setContentType("text/html;charset=utf-8");
            try {
                // 解析上传的数据,得到每个表单项
                List<FileItem> list = servletFileUpload.parseRequest(req);
                //判断每个表单项是文件还是普通类型
                for (FileItem fileItem:
                     list) {
                    //如果是普通的表单项
                    if (fileItem.isFormField())
                    {
                        //输出到页面
                            //设置文本输出流
                        //写到浏览器会出现乱码
                        PrintWriter out = resp.getWriter();
                        //普通的表单使用getString来获取值
                        out.write("表单的name值:" + fileItem.getFieldName() + "<br>");
                        out.write("普通的表单:"+ fileItem.getString("UTF-8") + "<br>");
                        System.out.println("表单的name值:" + fileItem.getFieldName());
                        System.out.println("普通的表单:"+ fileItem.getString("UTF-8"));
                    }
                    else
                    {
                        //如果是文件,则下载到服务器
                        PrintWriter out = resp.getWriter();
                        out.write("表单的name属性:"+ fileItem.getFieldName() + "<br>");
                        out.write("上传的文件名:" + fileItem.getName() + "<br>");
                        System.out.println("表单的name属性:"+ fileItem.getFieldName());
                        System.out.println("上传的文件名:" + fileItem.getName());

                        fileItem.write(new File("F:\\JavaProject\\0729_JSPTest" + fileItem.getName()));
                    }
                }





            } catch (FileUploadException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }


        }
        System.out.println("已收到上传的文件");
    }
}

在web.xml中配置servlet路径

    <servlet>
        <servlet-name>FileInputServlet</servlet-name>
        <servlet-class>com.teen.JSPTest0729.FileInputServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>FileInputServlet</servlet-name>
        <url-pattern>/inputPhoto</url-pattern>
    </servlet-mapping>

二、文件下载

同样需要在表单中添加属性

<form action="/0729_JSPTest/outputPhoto" method="post" enctype="multipart/form-data">
    <input type="submit" value="下载~">
</form>

创建ServletDownload类继承HttpServlet

同样重写doPost方法

首先要获取文件名存入字符串

通过getServletContext()获取上下文对象(看样子应该是个HTTP Servlet静态方法)

ServletContext servletContext = getServletContext();

通过上下文对象获得文件类型

String mimeType = servletContext.getMimeType("文件名.jpg");

通过响应头来告诉浏览器将要下载的文件类型

resq.setContentType(mimeType);

告诉浏览器此文件为附件,并对文件名进行UTF-8进行加密,因为谷歌浏览器会主动使用UTF-8解密

String fileHeader = "attachment;fileName =" + URLEncoder.encode("文件名.jpg","UTF-8");

resp.setHeader("Content-Disposition",fileHeader);

通过getResourceAsStream("文件路径")  获取上下文的输入流

InputStream resourceStream = servletContext.getResourceAsStream("文件路径");

通过响应头的getOutputStream()  获取响应输出流

OutputStream outputstream = resp.getOutputStream();

使用IO工具类来输出

IOUtils.copy(resourceStream,outputStream);

完整代码:

package com.teen.JSPTest0729;

import org.apache.commons.io.IOUtils;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;

/**
 * @author teen
 * @create 2021/7/29 18:38
 */
public class FileOutputServlet extends HttpServlet {
    

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取文件名
        String fileName = "微信1.jpg";
        //获取上下文对象
        ServletContext servletContext = getServletContext();
        //通过上下文对象获取文件类型
        String mimeType = servletContext.getMimeType("/微信1.jpg");
        System.out.println(mimeType);
        //通过响应头告诉浏览器文件类型
        resp.setContentType(mimeType);
        //告诉浏览器此文件为下载附件
            //对中文名进行utf-8加密
        String fileHeader = "attachment;fileName =" + URLEncoder.encode("微信1.jpg","UTF-8");
//        String fileHeader = "attachment; fileName =微信1.jpg";
        resp.setHeader("Content-Disposition",fileHeader);
        //获取上下文输入流getResourceAsStream
        InputStream resourceStream = servletContext.getResourceAsStream("/微信1.jpg");
        //设置响应输出流
        OutputStream outputStream = resp.getOutputStream();
        //使用IO工具类进行输出操作
        IOUtils.copy(resourceStream,outputStream);

        System.out.println("已将响应发送回客户端");
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值