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

文件的上传与下载

作者头像
栖西
发布2023-10-17 08:25:22
2770
发布2023-10-17 08:25:22
举报
文章被收录于专栏:栖西栖西
引言:平凡的生活中拥有一颗不甘于平凡的内心。

此篇文章,写的内容为文件的上传和下载,先写上传下载的位置为tomcat服务器,后期在填补位置在数据库的。

一、基于servlet实现

具体的步骤

代码语言:javascript
复制
1、要有form标签,method必须=post请求
2、form标签的enctype的属性值必须为multipart/form-data
3、在form标签中使用input type=file 添加上传的文件
4、编写服务器代码接受,处理上传的数据

文件上传时发送的HTTP协议内容,摘录部分:

代码语言:javascript
复制
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryTGxWXycKE3KZEeGq

enctype="multipart/form-data" 表示提交的数据,以多段(每一个表单项一个数据段)的形式进行拼接,然后以
二进制流的形式发送给服务器。
boundary 表示每段数据的分隔符
----WebKitFormBoundaryTGxWXycKE3KZEeGq	是由浏览器每次随机生成,就是每段数据的分界符
图片1
图片1

index.jsp

代码语言:javascript
复制
演示
<h2>文件上传下载演示</h2>
<form action="/upload" method="post" enctype="multipart/form-data">
    用户名:<input type="text" name="username"><br>
    头像:<input type="file" name="photo"><br>
    <input type="submit" value="提交">
</form>

后端接收的时候,仅用于调试,理解

代码语言:javascript
复制
// 以流的形式接收
ServletInputStream inputStream = req.getInputStream();

byte[] buffer = new byte[1024000];
int read = inputStream.read(buffer);  // 读了多少个字节
System.out.println(new String(buffer,0,read)); // 缓冲区放进来 从0开始读 read是读的长度
1、导包

commons-io commons-fileupload

创建一个maven工程,勾选模板,导入依赖

依赖如下:

代码语言:javascript
复制
	<dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
    </dependency>
    <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.4</version>
    </dependency>
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.4</version>
	</dependency>
2、常用类和方法
代码语言:javascript
复制
	ServletFileUpload类下的方法

        判断当前上传的数据格式是否是多段的格式
        boolean isMultipartContent(HttpServletRequest request)
	
	FileItem类下的方法
	
        解析上传的数据
        public List<FileItem> parseRequest(HttpServletRequest request)

        判断当前这个表单项,是否是普通的表单项,还是上传的文件类型。
            true	表示普通类型的表单项
            false	表示上传的文件类型
        boolean isFormField();

        获取表单项的name值
        String getFieldName();

        获取当前表单项的值
        String getFieldName();
	
		获取上传的文件名
		String getName();
		
		将上传的文件写到参数file所指向的磁盘位置
		void write(File file)
3、实现
代码语言:javascript
复制
新建了三个类
	TestBase64		测试Base64编码
	UploadServlet	上传
	Download		下载
配置web.xml

UploadServlet.java

代码语言:javascript
复制
package com;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
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.File;
import java.io.IOException;
import java.util.List;

// 文件上传
public class UploadServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // 设置页面编码 请求和响应的编码都为UTF-8 否则中文图片名上传的时候会乱码
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");

        System.out.println("文件上传了");
        // 1、先判断上传的数据是否是多段数据 (只有是多段的数据才是文件上传的)
        if(ServletFileUpload.isMultipartContent(req)){
            // 2、创建 FileItemFactory 工厂实现类
            FileItemFactory fileItemFactory = new DiskFileItemFactory();
            // 3、创建用于解析上传数据的工具类 ServletFileUpload
            ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory);
            try {
                // 4、调用解析方法,解析上传的数据,得到每一个表单项 fileItems
                List<FileItem> fileItems = servletFileUpload.parseRequest(req);
                // 循环判断,每一个表单项,是普通类型还是上传的文件
                for (FileItem fileItem : fileItems) {
                    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());

                        // 上传的位置  D:\AllTemp\data
                        fileItem.write(new File("D://AllTemp/data/"+fileItem.getName()));
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }
}

Download.java

代码语言:javascript
复制
package com;

import org.apache.commons.io.IOUtils;
import sun.misc.BASE64Encoder;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
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.net.URLEncoder;

public class Download  extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // 1、获取要下载的文件名
        String downloadFileName = "1.jpg";
        // 2、读取要下载的文件内容(通过ServletContext对象可以读取)
        ServletContext servletContext = getServletContext();

        // 获取要下载的文件类型
        String mimeType = servletContext.getMimeType("/file/" + downloadFileName);
        System.out.println("下载的文件类型:"+mimeType); // 下载的文件类型:image/jpeg
        // 4、在回传前,通过响应头告诉客户端返回的数据类型
        resp.setContentType(mimeType);
        // 5、还要告诉客户端收到的数据是用于下载使用(还是使用响应头)
        // Content-Disposition 表示收到的数据怎么处理
        // attachment 表示附件 ,下载使用
        // filename 表示指定下载的文件名
//        resp.setHeader("Content-Disposition","attachment;filename="+downloadFileName);

        // 可支持下载中文 文件名
        // URL 解决IE和谷歌的下载 中文乱码问题
        // BASE64 解决火狐浏览器的下载 中文乱码问题
        // 设置URL编码 URL编码是把汉字转化为%xx%xx的格式
//        resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode("风景图片999.jpg","UTF-8"));

        // 解决火狐浏览器的下载 中文乱码问题 需要修改请求头
        // Content-Disposition: attachment;filename==?charset?B?xxxxx?=
        // =?charset?B?xxxxx?= 进行说明
        // =?       表示编码内容的开始
        // charset  字符集
        // B        表示BASE64编码
        // xxxxx    表示文件名BASE64编码后的内容
        // ?=       表示编码内容的结束
//        resp.setHeader("Content-Disposition","attachment;filename==?UTF-8?B?"+new BASE64Encoder().encode("风景图片999.jpg".getBytes(    "UTF-8")) +"?=");


        // 请求头信息  进行判断 火狐或谷歌
        // User-Agent
        //	Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0
        if(req.getHeader("User-Agent").contains("Firefox")){
            // 如果是火狐浏览器使用 Base64编码
            resp.setHeader("Content-Disposition","attachment;filename==?UTF-8?B?"+new BASE64Encoder().encode("风景图片999.jpg".getBytes(    "UTF-8")) +"?=");
        }else {
            // 如果不是火狐  ,是谷歌或IE  使用URL编码
            resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode("风景图片999.jpg","UTF-8"));

        }

        // 这里放文件的路径  /斜杠被服务器解析表示 http://ip:端口号/工程名/  映射到  代码的 web目录
        // 我是在webapp下新建文件夹file  里面放了一张图片  图片名1.jpg
        InputStream resourceAsStream = servletContext.getResourceAsStream("/file/" + downloadFileName);

        // 获取响应的输出流
        ServletOutputStream outputStream = resp.getOutputStream();

        // 3、把下载的文件内容回传给客户端
        // 读取输入流中全部的数据,复制给输出流,输出给客户端
        IOUtils.copy(resourceAsStream,outputStream);




    }
}

TestBase64.java

代码语言:javascript
复制
package com;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;


public class TestBase64 {
    public static void main(String[] args) throws Exception {
        String content = "这是一段中文使用base64编码的内容";
        // 创建一个Base64编码器
        BASE64Encoder base64Encoder = new BASE64Encoder();
        // 执行Base64编码操作 对字节数组进行操作
        String encode = base64Encoder.encode(content.getBytes("UTF-8"));
        System.out.println(encode); // 6L+Z5piv5LiA5q615Lit5paH5L2/55SoYmFzZTY057yW56CB55qE5YaF5a65

        // 创建Base64解码器
        BASE64Decoder base64Decoder = new BASE64Decoder();
        //  解码操作
        byte[] bytes = base64Decoder.decodeBuffer(encode);
        String s1 = new String(bytes,"UTF-8");
        System.out.println(s1); // 这是一段中文使用base64编码的内容
    }
}

web.xml

代码语言:javascript
复制
	<servlet>
        <servlet-name>upload</servlet-name>
        <servlet-class>com.UploadServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>upload</servlet-name>
        <url-pattern>/upload</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>download</servlet-name>
        <servlet-class>com.Download</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>download</servlet-name>
        <url-pattern>/download</url-pattern>
    </servlet-mapping>
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-10-13,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引言:平凡的生活中拥有一颗不甘于平凡的内心。
  • 一、基于servlet实现
    • 1、导包
      • 2、常用类和方法
        • 3、实现
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档