天天看点

文件上传下载与String的一些知识点文件上传下载与String的一些知识点

文件上传下载与String的一些知识点

文件上传

文件上传依赖apache的commons组件的commons-fileupload.jar和commons-io.jar包

pom.xml引入依赖

<dependencies>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.5</version>
        </dependency>
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.4</version>
        </dependency>
    </dependencies>
           

jsp代码

<%--
  Created by IntelliJ IDEA.
  User: 15002
  Date: 2021/3/17
  Time: 9:46
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>文件上传</title>
  </head>
  <body>
    <form action="upload" enctype="multipart/form-data" method="post">
      名字:<input type="text" name="username">
      选择文件:<input type="file" name="file">
      <input type="submit" value="提交">
    </form>
  </body>
</html>

           

Servlet代码

package com.yyb.servlet;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;

/**
 * @Author FuGwaaa
 * @Date 2021/3/17 9:48
 * @Version 1.0
 */
@WebServlet("/upload")
public class UploadServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
        String realPath = this.getServletContext().getRealPath("/WEB-INF/upload");
        System.out.println("realPath"+realPath);
        File file = new File(realPath);
        System.out.println(file.exists());
        if (!file.exists()&&!file.isDirectory()){
            System.out.println("目录不存在");
            file.mkdir();
        }
        try {
        //1.创建DiskFileItemFactory工厂
        DiskFileItemFactory factory = new DiskFileItemFactory();
        //2.创建文件上传解析器
        ServletFileUpload fileUpload = new ServletFileUpload(factory);
        //解决乱码
        fileUpload.setHeaderEncoding("utf-8");
        //判断是否为上传表单数据
        if (!ServletFileUpload.isMultipartContent(request)) {
            //按传统接收方式
            System.out.println("传统传输方式");
            return;
        }
            //3.解析器解析request对象
            List<FileItem> fileItems = fileUpload.parseRequest(request);
            for (FileItem item : fileItems) {
                if (item.getFieldName().equals("username")){
                    String name = item.getFieldName();
                    String value = item.getString("utf-8");
                    System.out.println(name+":"+value);
                }else{
                    String name = item.getName();
                    if (name==null||name.trim().equals("")){
                        continue;
                    }
                    String fileName = name.substring(name.lastIndexOf(File.separator) + 1);
                    InputStream is = item.getInputStream();
                    FileOutputStream os = new FileOutputStream(realPath + File.separator + fileName);
                    byte[] buffer = new byte[1024];
                    int len = 0;
                    while((len=is.read(buffer))>0){
                        os.write(buffer,0,len);
                    }
                    is.close();
                    os.close();
                    //删除处理文件上传时产生的临时文件
                    item.delete();
                }
            }
        } catch (FileUploadException e) {
            e.printStackTrace();
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException {
        this.doPost(request,response);
    }
}
           

主要步骤如下:

1.创建工厂类DiskFileItemFactory对象:

DiskFileItemFactory factory = new DiskFileItemFactory() ;

2.使用工厂创建解析器对象:

ServletFileUpload fileUpload = new ServletFileUpload(factory) ;

3.使用解析器来解析request对象:

List list = fileUpload.parseRequest(request);

关于item.getFileName()与item.getName()

  • getFileName()是获得字段名,比如:jsp表单的name(username)
  • getName()是获得上传文件名,比如:上传文件时(a.txt)

文件上传总结

在这里刚开始犯了一个低级错误,在写Servlet时@WebServlet("/upload")忘写了**/,导致报错,经过很长时间的寻找发现是没有/**,在此记录希望以后不要再犯这样的低级错误。

文件上传下载与String的一些知识点文件上传下载与String的一些知识点

jsp页面在写的时候form表单的enctype属性要写为multipart/form-data;

this.getServletContext().getRealPath()

在写Servlet页面时想要获取到WEB-INF新建upload文件夹来存放上传的数据,

this.getServletContext().getRealPath()

这个方法是获得当前打包的WEB-INF的绝对路径,所以

this.getServletContext().getRealPath("/WEB-INF/upload")

的绝对路径为

E:\JAVA\self-study\fileUpload\out\artifacts\fileUpload_war_exploded\WEB-INF\upload

在这里我想总结下关于相对路径的知识,一般相对路径有三种写法分别为

./

,

/

,

../

文件上传下载与String的一些知识点文件上传下载与String的一些知识点
  • ./

    代表访问本级目录下的文件,例如index.jsp要引用index.html就需要用到相对路径“./index.html”或者直接"index,html"
  • ../

    代表访问上一级目录文件,例如register.html要引用login.html相对路径的写法为"…/login.html"
  • /

    代表访问根目录文件,就是最顶端的文件夹,注意这里例如register.html的根目录就为web,所以要引用index.jsp写法为"/index.jsp"

关于mkdir()与mkdirs()方法

mkdir()方法创建文件夹时如果父目录不存在则不创建

mkdirs()方法创建文件夹时如果父目录不存在依旧创建,从不存在的文件夹开始创建创建多个文件夹

文件下载

fileList.jsp

<%--
  Created by IntelliJ IDEA.
  User: 15002
  Date: 2021/3/18
  Time: 10:58
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>文件列表</title>
</head>
<body>
<h1>点击下载</h1>
    <c:forEach items="${list}" var="file">
        <a href="downLoad?filename=${file.name}" target="_blank" rel="external nofollow" >${file.name}</a>
        <br>
    </c:forEach>
</body>
</html>

           

Servlet

package com.yyb.servlet;

import javax.servlet.ServletException;
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.IOException;

/**
 * @Author FuGwaaa
 * @Date 2021/3/18 10:56
 * @Version 1.0
 */
@WebServlet("/fileList")
public class FileListServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String realPath = this.getServletContext().getRealPath("/WEB-INF/upload");
        File file = new File(realPath);
        File[] files = file.listFiles();
        for (File f : files) {
            System.out.println(f.getName());
        }
        request.setAttribute("list",files);
        request.getRequestDispatcher("fileList.jsp").forward(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}
           
package com.yyb.servlet;

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;

/**
 * @Author FuGwaaa
 * @Date 2021/3/18 11:05
 * @Version 1.0
 */
@WebServlet("/downLoad") public class DownLoadServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String realPath = this.getServletContext().getRealPath("/WEB-INF/upload");
        String filename = request.getParameter("filename");
        File file = new File(realPath + File.separator + filename);
        if (!file.exists()){
            System.out.println("您要下载的文件已经被删除");
            return;
        }
        //配置response头
        response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
        FileInputStream fis = new FileInputStream(realPath + File.separator + filename);
        ServletOutputStream os = response.getOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = fis.read(buffer))>0){
            os.write(buffer,0,len);
        }
        os.close();
        fis.close();
    }

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

文件下载总结

文件上传时解析器解析requst对象,然后得到输入流,new输出流;而文件下载时new 输入流,然后配置response.setHeader,通过response得到输出流。

不管上传下载都会有

byte[] buffer = new byte[1024];
int len = 0;
while ((len = fis.read(buffer))>0){
       os.write(buffer,0,len);
}
           

记得关闭输入输出流

特别注意:idea中使用maven引入jar时如果要在WEB-INF/lib下用记得在项目配置的artifacts中的put into /WEB-INF/lib

文件上传下载与String的一些知识点文件上传下载与String的一些知识点

关于String类的也在这里总结下

常用方法

返回值 方法名 作用
int length() 得到一个字符串的字符个数(一个中文是一个字符,一个英文是一个字符,一个转义字符是一个字符)
char[] toCharArray() 将一个字符串转换成字符数组
String[] split(String) 将一个字符串按照指定内容劈开
boolean equals(String) 判断两个字符串的内容是否一模一样
boolean equalsIgnoreCase(String) 忽略大小写的比较两个字符串的内容是否一模一样
boolean contains(String) 判断一个字符串里面是否包含指定的内容
boolean startsWith(String) 判断一个字符串是否以指定的内容开头
boolean endsWith(String) 判断一个字符串是否以指定的内容结尾
String toUpperCase() 将一个字符串全部转换成大写
String toLowerCase() 将一个字符串全部转换成小写
String substring(int) 从指定下标开始一直截取到字符串的最后
String substring(int,int) 从下标x截取到下标y-1对应的元素
String trim() 去除一个字符串的前后空格
int indexOf(String) 得到指定内容第一次出现的下标
int lastIndexOf(String) 得到指定内容最后一次出现的下标

String与new String()的区别

String s1 = "abc"

当常量池中没有”abc“字符串时在常量池中创建,返回给s1;如果有“abc”字符串对象,则直接返回给s1。

public class Test {
    public static void main(String[] args) {
        String s1 = "abc";
        String s2 = "abc";
        String s3 = s1;
        System.out.println(s1==s2);
        System.out.println(s1==s3);
    }
}
           

运行结果

true
true
           

String s2 = new String("abc")

,如果常量池中没有“abc”字符串对象,则在常量池中创建,并且在堆中创建对象,返回地址给s2;如果常量池中有“abc“字符串对象,则直接在堆中创建对象,返回地址。

public class Test {
    public static void main(String[] args) {
        String s1 = "abc";
        String s2 = new String("abc");
        String s3 = new String("abc");
        System.out.println(s1==s2);
        System.out.println(s2==s3);
    }
}
           

运行结果

false
false
           

池中创建,并且在堆中创建对象,返回地址给s2;如果常量池中有“abc“字符串对象,则直接在堆中创建对象,返回地址。

public class Test {
    public static void main(String[] args) {
        String s1 = "abc";
        String s2 = new String("abc");
        String s3 = new String("abc");
        System.out.println(s1==s2);
        System.out.println(s2==s3);
    }
}
           

运行结果

false
false