前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >文件的上传和下载

文件的上传和下载

作者头像
技术交流
发布2022-11-18 17:04:00
1.3K0
发布2022-11-18 17:04:00
举报
文章被收录于专栏:@学习笔记@学习笔记

文章目录


前言

文件的上传和下载,是非常常见的功能,在很多的系统中,或者软件中都经常使用文件的上传和下载。 比如:QQ头像,就使用了上传 邮箱中也有附件的上传和下载的功能


一、文件的上传介绍

1、要有一个form标签,method = post 请求 2、form标签的encType属性值必须为multipart/form-data值 3、在form标签中使用input type=file添加上传文件 4、编写服务器代码(Servlet程序)接收,处理上传的数据。

encType = multipart/form-data 表示提交的数据,以多段(每一个表单项一个数据段)的形式进行拼接,然后以二进制流的形式发送给服务器

1.1、文件上传,HTTP协议的说明

在这里插入图片描述
在这里插入图片描述

1.2、commons-fileupload.jar 常用API介绍说明

commons-fileupload.jar 需要依赖commons-io.jar这个包,所以两个包我们都要引入。 第一步,就是需要导入两个jar包; commons-fileupload.jar commons-io.jar 这两个jar包中常用的类和方法: ServletFileUpload类,用于解析上传的数据 FileItem类,表示每一个表单项 boolean ServletFileUpload.isMultipartContent(HttpServletRequest request); 判断当前上传的数据格式是否是多段的格式

在这里插入图片描述
在这里插入图片描述

String FileItem.getString(); 获取当前表单项的值 String FileItem,getName(); 获取上传的文件名 String FileItem,write(file); 将上传的文件写到参数file所指向的硬盘位置。

1.3、fileupload类库的使用:

上传文件的表单:

代码语言:javascript
复制
<body>
<form action="uploadServlet" method="post" enctype="multipart/form-data">
    用户名:<input type="text" name="username" /><br>
    头像:<input type="file" name="photo" /><br>
    <input type="submit" value="上传" />
</form>
</body>

解析上传的数据的代码:

代码语言:javascript
复制
public class UploadServlet 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);
            try {
                //解析上传数据,得到每一个表单项FileItem
                List<FileItem> list = servletFileUpload.parseRequest(req);
                for(FileItem fileItem : list) {
                    if(fileItem.isFormField()) {
                        //普通表单项
                        System.out.println("表单项的name属性值: " + fileItem.getFieldName());
                        //参数UTF-8解决乱码问题
                        System.out.println("表单项的value属性值: " + fileItem.getString("UTF-8"));
                    } else {
                        //上传的文件
                        System.out.println("表单项的name属性值: " + fileItem.getFieldName());
                        System.out.println("上传的文件名: " + fileItem.getName());
                        fileItem.write(new File("E:\\"+ fileItem.getName()));
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

结果:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、文件下载

下载常用的API说明: response.getOutputStream(); servletContext.getResourceAsStream(); servletContext.getMimeType(); response.setContentType();

response.setHeader(“Content-Disposition”,“attachment; fileName = 文件名.文件类型”); 这个响应头告诉浏览器,这是需要下载的。而attachment表示附件,也就是下载的一个文件。fileName=后面表示下载的文件名。 完成上面的两个步骤,下载文件是没问题了。但是我们要下载的文件是中文名的话,会发现下载无法正确显示出正确的中文名。 原因是在响应头中,不能包含有中文的字符,只能包含ASCII码。 文件下载示例:

代码语言:javascript
复制
public class DownloadServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取要下载的文件名
        String downloadFileName = "宇航员.jpg";
        //读取要下载的文件内容(通过ServletContext对象可以读取)
        ServletContext servletContext = getServletContext();
        //获取要下载的文件类型
        String mimeType = servletContext.getMimeType("/file/" + downloadFileName);
        System.out.println("下载的文件类型: " + mimeType);
        //在回传前,通过响应头告诉客户端返回的数据类型
        resp.setContentType(mimeType);
        //还要告诉客户端收到的数据是用于下载使用(还是使用响应头)
/*        Content-Disposition 响应头,表示收到的数据怎么处理
          attachment 表示附件,表示下载使用
          filename   表示指定下载的文件名*/
        //把中文名进行UTF-8编码操作
        String str = "attachment; fileName=" + URLEncoder.encode("宇航员.jpg","UTF-8");
        resp.setHeader("Content-Disposition",str);
        InputStream resourceAsStream = servletContext.getResourceAsStream("file/" + downloadFileName);
        //获取响应输出流
        OutputStream outputStream = resp.getOutputStream();
        //把下载的文件内容回传给客户端
        //读取输入流中全部的数据,复制给输出流,输出给客户端
        IOUtils.copy(resourceAsStream,outputStream);
    }
}
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、附件中文名乱码的解决方案:

方案一:URLEncoder解决IE和谷歌浏览器中的附件中文名问题

如果客户端浏览器是IE浏览器或者是谷歌浏览器,我们需要使用URLEncoder类先对中文名进行UTF-8的编码操作。 因为IE浏览器和谷歌浏览器收到含有编码的字符串后会以UTF-8字符集进行解码显示。

代码语言:javascript
复制
        //把中文名进行UTF-8编码操作
        String str = "attachment; fileName=" + URLEncoder.encode("宇航员.jpg","UTF-8");
        resp.setHeader("Content-Disposition",str);

方案二:BASE64编解码解决火狐浏览器的附件中文名问题

如果客户端浏览器是火狐浏览器,那么我们需要对中文名进行BASE64的编码操作。

在这里插入图片描述
在这里插入图片描述

BASE64编解码操作:

代码语言:javascript
复制
 public static void main(String[] args) throws Exception {
        String content = "这是需要Base64编码的内容";
        // 创建一个Base64编码器
        BASE64Encoder base64Encoder = new BASE64Encoder();
        // 执行Base64编码操作
        String encodedString = base64Encoder.encode(content.getBytes("UTF-8"));

        System.out.println( encodedString );
        // 创建Base64解码器
        BASE64Decoder base64Decoder = new BASE64Decoder();
        // 解码操作
        byte[] bytes = base64Decoder.decodeBuffer(encodedString);

        String str = new String(bytes, "UTF-8");

        System.out.println(str);
    }

因为火狐浏览器使用的是BASE64的编解码方式还原响应中的汉字,所以需要使用BASE64Encoder类进行编码操作。 注:BASE64Encoder类在高版本的JDK中已经被抛弃使用了。所以用这个类慎用!

总结以上两种解决方案

我们只需要通过判断请求头中User-Agent这个请求头携带过来的浏览器信息即可判断出是什么浏览器。 如下:

代码语言:javascript
复制
 if (req.getHeader("User-Agent").contains("Firefox")) {
            // 如果是火狐浏览器使用Base64编码
            resp.setHeader("Content-Disposition", "attachment; filename==?UTF-8?B?" + new BASE64Encoder().encode("中文.jpg".getBytes("UTF-8")) + "?=");
        } else {
            // 如果不是火狐,是IE或谷歌,使用URL编码操作
            resp.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("中文.jpg", "UTF-8"));
        }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-10-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 前言
  • 一、文件的上传介绍
    • 1.1、文件上传,HTTP协议的说明
      • 1.2、commons-fileupload.jar 常用API介绍说明
        • 1.3、fileupload类库的使用:
        • 二、文件下载
        • 三、附件中文名乱码的解决方案:
          • 方案一:URLEncoder解决IE和谷歌浏览器中的附件中文名问题
            • 方案二:BASE64编解码解决火狐浏览器的附件中文名问题
              • 总结以上两种解决方案
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档