文件的上传的概念了解

文件上传

操作

  • 在web页面上添加传输入项
  • 在Servlet中读取上传文件的数据,并保存到(服务器)本地硬盘中。

表单形式的上传文件

  • 在 中name必须有,否则浏览器不会上传文件的数据。
  • 表单的方法method=”post“,enctype=”multipart/form-data“类型
  • 默认的enctype不会上传文件的数据,只会上传文件的名称。
  • 通过表单将表单中的数据存放到Http的消息请求体中,并且通过MIME类型进行描述,在Servlet可以通过采用request.getInputStream()方法读取到客户段发送来的数据,但是在Servlet中读取并且解析相应文件是相当的麻烦的。所以提供了一个开源组件Commons-FileUpload。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="#" method="post " enctype="multipart/form-data">
    上传文件:<input type="file" name="filName"><br>
    登录:<input type="submit" value="登录">
</form>
</body>
</html>

在这里插入图片描述

FileItem接口

用于封装单个表单字段元素的数据。

  • isFormField() 判断FileItem对象封装的是否是一个普通文本表单字段 ;
  • String getName() 获取文件的上传字段的文件名
  • String getFieldName() : 获取表单字段描述头的name的属性值
  • void write(File file) : 将FileItem对象保存到指定的文件中,
  • String getString(): 将FileItem对象中保存的数据流内容以一个字符串返回,
  • String getContentType() : 获取上传文件的类型
  • Boolean isInMemory() : 判断FileItem对象封装的数据内容存储在内存中,还是在临时的内存中。
  • void delete() 清空FileItem中存放的内容
  • inputStream getInputStream() 以流的形式返回上传文件的数据内容
  • long getSize() : 返回上传文件的大小(字节为单位)

DiskFileItemFactory

  • 将消息体中的每个文件封装成单独FileItem对象,文件小,存到内存中,文件大,以临时文件存储。
  • 它的构造方法
  • DiskFileItemFactory() : 采用默认的临界值和系统临时文件夹构造文件工厂对象。
  • DiskFileItemFactory(int size Threshold,File repository) : 采用设定的临界值和系统临时文件夹构造文件工厂对象。
  • 它的方法
  • FileItem createItem(String fieldName,String contentType, boolean isFormField,String fileName);
  • setSizeThreshold(int sizethreshold) 和getSizeThreshold()
  • setRepository(File repository) 和get Repository.

ServletFileUpload

处理文件上传的核心类

  • 构造方法
  • ServletFileUpload():方法构造一个未初始化的实例对象
  • ServletFileUpload (FileItemFactory fileItemFactory) 根据指定参数的FileItemFactory对象创建一个ServeltFileUpload对象,
  • 方法
  • setSizeMax(long sizeMax) 和getSizeMax()方法: 用于设置请求消息实体内容的最大限制
  • parseRequest(): 对Http请求消息体内容进行解析入口,解释出form表单中每个字段的数据,并封装成FileItem对象中,将对象加入到list集合中。
  • setFileSizeMax()和getFileSizeMax()
  • getItemIterator():迭代器,保存时FileItemStream对象
  • isMultiparContent: 是消息体内容是否是”multipart/form-data“类型
  • getFileItemFactory()
  • setHeaderEncoding(): 用于设置读取和设置编码

实现文件上传

  • 过程
  • 导入Jar包
  • 准备上传网页,form.jsp
  • 处理请求的Servlet

form.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="UploadServlet" method="post" enctype="multipart/form-data">
    <%--上传文件:<input type="file" name="filName"><br>--%>
    <%--登录:<input type="submit" value="登录">--%>
    <table width="600px">
        <tr>
            <td>上传者</td>
            <td>
               <input type="text" name="name">
            </td>
        </tr>
        <tr>
            <td>上传文件</td>
            <td>
                <input type="file" name="myfile">
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <input type="submit" value="上传">
            </td>
        </tr>
    </table>
</form>
</body>
</html>

UploadServlet

package com.yue;

import org.apache.commons.fileupload.FileItem;
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;
import java.util.UUID;

public class UploadServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        try {
            //设置ContentType的值
            resp.setContentType("text/html;charset=utf-8");
            //创建DiskFileItemFactory工厂对象
            DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
            //设置文件缓存目录,如果目录不存在就新建一个
            File file = new File("E:\\new");
            if (!file.exists()) {
                file.mkdirs();
            }
            //设置缓存路径
            diskFileItemFactory.setRepository(file);
            //创建ServletFileUpload对象
            ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
            //设置字符编码
            servletFileUpload.setHeaderEncoding("utf-8");
            //解析request,得到上传文件FileItem对象
            List<FileItem> fileItems = servletFileUpload.parseRequest(req);
            //获取字符流
            PrintWriter writer = resp.getWriter();
            //遍历集合
            for (FileItem fileItem : fileItems) {
                //判断是否是普通字段
                if (fileItem.isFormField()) {
                    //获得字段名和字段值
                    String name = fileItem.getFieldName();
                    if (name.equals("name")) {
                        //如果文件不为空,将其保存在value中
                        if (!fileItem.getString().equals("")) {
                            String value = fileItem.getString("utf-8");
                            writer.print("上传者:" + value + "<br/>");
                        }
                    }
                }else {
                    //获取上传的文件名
                    String name = fileItem.getName();
                    if(name != null && !name.equals("")){
                        writer.print("上传者文件名称是:" +name + "<br/>");
                    }
                    //截取出文件名
                    name = name.substring(name.lastIndexOf("\\") + 1);
                    //文件名需要唯一性
                    name = UUID.randomUUID().toString() + "_" + name;
                     //在服务器创建同名文件
                    String webPath = "/upload";
                    //将服务器中文件加路径域文件名组合成完整的服务器端路径
                    String realPath = getServletContext().getRealPath(webPath + name);

                    //创建文件
                    File file1 = new File(realPath);
                    file1.getParentFile().mkdirs();
                    file1.createNewFile();
                    //获得上传文件流
                    InputStream inputStream = fileItem.getInputStream();
                    //使用FileoutputStream打开服务器端上传文件
                    FileOutputStream fileOutputStream = new FileOutputStream(file1);
                    //流的拷贝
                    byte[] bytes = new byte[1024];//每次读取一个字节
                    int len;
                    //开始读取上传文件的字节,并将其输出到服务器的上传文件输出流中
                    while((len = inputStream.read(bytes))>0){
                        fileOutputStream.write(bytes,0,len);
                        //关闭流
                        inputStream.close();
                        fileOutputStream.close();
                        //删除临时文件
                        fileItem.delete();
                        writer.print("上传文件成功!<br/>");
                    }
                }
            }
        }catch (Exception e){
           throw new RuntimeException(e);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}

文件的下载

文件的下载:从服务器端把文件保存到本地
文件的下载:一个流两个头
>>> 一个流:文件的字节输入流
>>> 两个头(相应头):
Content-Type:对应文件的MIME的类型,可以理解为文件的扩展名
Content-Dispostion:以下载框的方式保存文件。

download.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title>Title</title>
</head>
<body>
<a href="/chapter12/DownloadServlet?filename=1.jpg">下载文件</a>
</body>
</html>

DownLoadServlet

package com.yue;

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;

public class DownloadServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //解决中文乱码问题
        resp.setContentType("text/html;charset=utf-8");
        //获取下载文件的名称,在这里可以使用req和resp,这里的下载的servletfileupload和上传的没有关系。
        String filename = req.getParameter("filename");
//        String filename = "1.jpg";
        //获取文件的类型
//        String mimeType = getServletContext().getMimeType(filename);
        //通知浏览器以下载的方式打开
        resp.setHeader("Content-Type","application/octet-stream");
        resp.setHeader("Content-Disposition","attachment;filename="+filename);
        String folder ="/download";
        //获取文件的字节输入流
        InputStream resourceAsStream = getServletContext().getResourceAsStream(folder + filename);
        //获取文件的字节输出流
        ServletOutputStream outputStream = resp.getOutputStream();
        byte[] bytes = new byte[1024];
        int len;
        while((len = resourceAsStream.read(bytes) )!=-1){
            outputStream.write(bytes,0,len);
        }
        outputStream.close();
        resourceAsStream.close();
    }

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

解决上传文件名中文乱码问题

方式一
在download.jsp
<a href="/chapter12/DownloadServlet?filename=<%=URLEncoder.encode(“风景.jpg”, “utf-8”)%>">下载文件是中文1
在DownloadServlet
resp.setHeader(“Content-Disposition”,“attachment;filename=”+ URLEncoder.encode(filename,“utf-8”));
只在IE浏览器中有效
方式二
添加一个工具类

DownUtils

根据浏览器的不同,进行不同的编码

package com.yue;

import sun.misc.BASE64Encoder;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

public class DownUtils {
    public static String filenameEncoding(String filename, HttpServletRequest request) throws UnsupportedEncodingException {
        // 获得请求头中的User-Agent
        String agent = request.getHeader("User-Agent");
        // 根据不同的客户端进行不同的编码

        if (agent.contains("MSIE")) {
            // IE浏览器
            filename = URLEncoder.encode(filename, "utf-8");
        } else if (agent.contains("Firefox")) {
            // 火狐浏览器
            BASE64Encoder base64Encoder = new BASE64Encoder();
            filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
        } else {
            // 其它浏览器
            filename = URLEncoder.encode(filename, "utf-8");
        }
        return filename;
    }
}

DownloadServlet

package com.yue;

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 DownloadServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //解决中文乱码问题
        resp.setContentType("text/html;charset=utf-8");
        //获取下载文件的名称,在这里可以使用req和resp,这里的下载的servletfileupload和上传的没有关系。
        String filename = req.getParameter("filename");
//        String filename = "1.jpg";
        //获取文件的类型
//        String mimeType = getServletContext().getMimeType(filename);
        //通知浏览器以下载的方式打开
        resp.setHeader("Content-Type","application/octet-stream");
        resp.setHeader("Content-Disposition","attachment;filename="+filename);
        //中文方式1
//        resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(filename,"utf-8"));
        //中文方式2
//        filename = DownUtils.filenameEncoding(filename, req);
//        resp.setHeader("Content-Disposition","attachment;filename="+filename);
        String folder ="/download";
        //获取文件的字节输入流
        InputStream resourceAsStream = getServletContext().getResourceAsStream(folder + filename);
        //获取文件的字节输出流
        ServletOutputStream outputStream = resp.getOutputStream();
        byte[] bytes = new byte[1024];
        int len;
        while((len = resourceAsStream.read(bytes) )!=-1){
            outputStream.write(bytes,0,len);
        }
        outputStream.close();
        resourceAsStream.close();
    }

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

download.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@page import="java.net.URLEncoder"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title>Title</title>
</head>
<body>
<a href="/chapter12/DownloadServlet?filename=1.jpg">下载文件</a>
<br/>
<a href="/chapter12/DownloadServlet?filename=<%=URLEncoder.encode("风景.jpg", "utf-8")%>">下载文件是中文1</a>
<br>
<a href="/chapter12/DownloadServlet?filename=风景.jpg">下载文件是中文2</a>
</body>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值