Java Web 十四 文件上传

十四 文件上传

14.1 概念及原理

本质就是将一台电脑中的文件根据网络协议通过io流传递到另外一台电脑(服务器)上

网络编程
	ip:电脑在网络中的唯一标识
  	port:软件在电脑中的唯一标识
  	协议:不同设备进行沟通的规则!
概念:
	当用户在前端页面点击文件上传后,文件数据交给服务器端,实现保存
步骤:	
	编写文件上传表单
	编写服务器程序接收文件

文件上传表单提交方式:post
表单提交类型:mulitipart/form-data

14.2 页面实现
<form action="" method="post" enctype="multipart/form-data">
    文件:<input type="file" name="up">
    <input type="submit" value="上传">
</form>
14.3 编写服务器程序
核心步骤:
	· 编写Servlet
	· 使用@MultipartConfig注解
	· 使用javax.servlet.http.Part接口接收文件类型
14.3.1 文件上传
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.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

/**
 * 文件上传
 * 如果让Servlet支持文件上传,需要加一个注解@MultipartConfig(servlet3.0以后才有)
 */
@WebServlet(name = "UploadServlet", urlPatterns = "/upload")
// maxFileSize单个文件大小,单位字节;
// maxRequestSize请求中多个文件的总大小;
@MultipartConfig(maxFileSize = 1024 * 1024, maxRequestSize = 1024 * 1024 * 2)
public class UploadServlet extends HttpServlet {

    // 限制上传文件类型
    private List<String> FILE_TYPES = new ArrayList<>();

    public UploadServlet() {
        FILE_TYPES.add(".jpg");
        FILE_TYPES.add(".png");
        FILE_TYPES.add("gif");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //拿到文件
        Part part = request.getPart("up");
        String fileName = part.getSubmittedFileName();//用户上传的文件名
        String ext = fileName.substring(fileName.lastIndexOf("."));//扩展名
        PrintWriter writer = response.getWriter();
        if (FILE_TYPES.contains(ext)) {
            part.write("D:\\upload\\" + System.currentTimeMillis() + ext);//以文件流的形式存入磁盘,加上时间戳
            writer.write("上传成功");
        } else {
            writer.write("文件格式错误");
        }

    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}
安全问题:
	上传文件应该放在外界无法直接访问的目录下(WEB-INF目录下)。

文件覆盖:
	初级阶段增加时间戳 System.currentTimeMillis()

文件类型限制:
	在收到上传文件名师,判断后缀是否合法。
13.3.2 文件下载
首先要有一个页面列出上传文件目录下的所有文件
当用户点击文件下载超链接时进行下载操作。

获取客户需要下载的文件名,使用流读取后,并返回给浏览器
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.net.URLEncoder;

@WebServlet(name = "DownloadServlet", urlPatterns = "/download")
public class DownloadServlet extends HttpServlet {
    private String path = "D:\\load\\";// 服务端存放文件的地方
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String name = request.getParameter("name");
        response.setHeader("content-disposition","attachment:filename="+ URLEncoder.encode(name,"utf-8"));
        File file = new File(path+name);
        FileInputStream inputStream = new FileInputStream(file);//从系统中读取文件
        ServletOutputStream outputStream = response.getOutputStream();// 响应流
        // 从水池1中取水,放到水池2
        byte[] buf = new byte[1024];//水桶
        int len = 0;//水桶每次从水池1拿多少水,等于-1,代表水池已经空了
        while ((len = inputStream.read(buf))!=-1) {//从水池1中给水桶灌水
            outputStream.write(buf,0,len);//把水桶里的水,倒进水池2,偏移量 最后一次可能桶没装满
        }
        outputStream.close();
        inputStream.close();
    }

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

添加响应头:content-disposition,浏览器保存文件
中文文件名需要编码

13.3.3 多文件上传
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.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@WebServlet(name = "MutilUploadServlet", urlPatterns = "/mutilupload")
@MultipartConfig(maxFileSize = 1024 * 1024, maxRequestSize = 1024 * 1024 * 2)
public class MutilUploadServlet extends HttpServlet {
    private List<String> FILE_TYPES = new ArrayList<>();

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        //拿到文件
        Collection<Part> parts = request.getParts();//多文件上传,拿到的是请求中所有的内容,包括文字和文件
        for (Part part : parts) {
            String name = part.getName();//参数名
            String fileName = part.getSubmittedFileName();//代表当前的part是一个文字参数,文字参数没有文件名
            if (fileName != null) {//是文件
                System.out.println("文件名" + fileName);
                System.out.println(request.getRemoteAddr());
                String ext = fileName.substring(fileName.lastIndexOf("."));
                PrintWriter writer = response.getWriter();
                if (FILE_TYPES.contains(ext)) {
                    part.write("D:\\upload\\" + System.currentTimeMillis() + ext);//以文件流的形式,写入磁盘
                    writer.write("上传成功");
                } else {
                    writer.write("文件格式错误");
                }
            } else {
                System.out.println(name + "=" + request.getParameter(name));
            }
        }
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值