Servlet的应用(二):文件上传

一:项目的框架

 二:Web前端设计部分

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件上传页面</title>
</head>
<body>
<!--
1.文件的上传必须是post,因为post请求的数据是放在请求体中的,可以携带大量的数据
2.第二步enctype的值必须是:多媒体的表单数据,文件的上传必须要这个参数
-->
<form method="post" enctype="multipart/form-data" action="file">
    File:<input type="file" name="avatar"><br>
    <input type="submit">

</form>
</body>
</html>

                                                                    效果如下:

 

三:Servlet设计部分

//这是一个用来上传文件到服务器的servlet
package com.whx.servlet;

import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerOutputVisitor;

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.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.UUID;

@WebServlet(value="/file" , name="FileServlet")
@MultipartConfig  //这是告诉servlet,你处理的是一个多媒体表单数据
public class FileServlet extends HttpServlet {

    //定义文件上传之后 保存的路径的目录
    private String fileLocation = "E:\\nginx\\nginx-1.17.2\\html\\";

    //定义
    private String fileServer ="Http://localhost/";

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //设置上传文件的默认编码方式
        req.setCharacterEncoding("utf-8");

        //获取上传的文件的所有的信息,part中封装了要上传的文件的所有信息
        Part part = req.getPart("avatar");
        System.out.println(part);

        //=============获取上传的文件的文件名(目的是可以补充到保存文件的路径当中,构成一个完整的路径)======================

        //注意: part.getName(): 获取的 !!!并不是文件的名字
        //      要获取文件的名字, 文件名是存储在Part的头部的"content-disposition"中
        //      所以要想获取文件的名字,必须要先获取文件的头部(参数中填 content-disposition)
        //       eg: contentDisposition的数据内容是: form-data; name="avatar"; filename="4月8日复习.txt"
        String contentDisposition = part.getHeader("content-disposition");

        // 下一步是要从contentDisposition中获取filename的内容
        //1.
        String filePrefix = "filename=\""; // \"为转义字符
        //2. 获取文件名开始位置所在的索引
        int index = contentDisposition.indexOf(filePrefix) + filePrefix.length();
        //3.获取文件名 contentDisposition.length()-1 的原因是 因为最后有个"
        String fileName = contentDisposition.substring(index, contentDisposition.length() - 1);
        //4.获取文件的后缀名: .png .txt .jpg
        String fileSuffix = fileName.substring(fileName.indexOf("."));
        //5.为了避免上传的文件会有因为重名而导致保存失败的事件的发生 那么我们可以随机生成一个字符串来给上传的文件命名
        String newFileName = UUID.randomUUID().toString() + fileSuffix;

        // 利用part获取文件的输入流
        InputStream is = part.getInputStream();

        //获取文件输出流 (输出流的目标是:文件保存的路径) fileLocation是上传文件默认的保存目录  newFileName是上传的文件的新的名字
        FileOutputStream os = new FileOutputStream(fileLocation + newFileName);

        //存储IO流每次读取的数据
        byte[] bs = new byte[1024];

        //每次读取的有效数字
        int length = 0;

        //读取上传文件的同时 往服务器本地保存文件数据
        while ( -1 != ( length = is.read(bs))){
            os.write(bs,0,length);
        }
        //读取完毕 释放资源
        os.flush();
        os.close();
        is.close();


        // ==============================以下是服务器对html页面请求的回应============================================
        //设置页面的默认编码方式
        resp.setContentType("text/html;charset=utf-8");
        //获取输出流
        PrintWriter writer = resp.getWriter();

        //获取StringBuffer进行html语句的拼接
        StringBuffer html = new StringBuffer();
        html.append("<html>")
                .append("<head></head>")
                .append("<body><h1>上传成功</h1>")
                // fileServer + newFileName = http://localhost/0dc725b1-5b12-4865-bbd0-2fbed66b9e7e.png
                .append("<img src=\"" + fileServer + newFileName + "\">")
                //.append("<video src=\"" + fileServer + newFileName + "\" width=\"600\" height=\"400\" autoplay>")
                .append("</body></html>");

        writer.write(html.toString());
        writer.flush();
        writer.close();

    }
}

 四:注意事项

(1)HTML: 

       1.文件上传的方法必须是post,因为get的大小有限而post请求的数据是放在请求体重的,可以携带大量的数据

       2.enctype的值必须是: multipart/form-data :多媒体表单数据,文件的上传必须是这个参数

       3.action中的值必须得和servlet中的注释WebServlet中的value的值对应起来,两者必须取名相同

          action中的值不加"/"表示这是相对路径

       4.文件上传,type为"file"的input标签中name的值要与servlet获取文件信息的getPart方法的参数联系起来


(2)Servlet:

        1.文件上传必须要有两个注解: 一个是WebServlet(这个中value的值是用来和HTML页面action的值绑定起来的)

                                                         另一个是MultipartConfig   这个是标记这个Servlet处理的是一个多媒体表单数据

        2.文件上传需要获取: 上传文件的信息: 文件的名字 文件的后缀名

                                          文件的信息可以通过getPart(参数)方法获取;

                                          文件的名字存放在文件的头部中,文件的头部信息,可以通过getHeader(参数)获取 参数是"content-disposition";

                                          通过文件的头部信息,可以通过字符串类的api来截取

 

 (3)编码问题

         1.设置上传文件的默认编码方式

 //设置上传文件的默认编码方式
        req.setCharacterEncoding("utf-8");

         2.设置文件输出到HTML页面的默认编码方式

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

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值