一、开发环境的搭建:

jsp springboot上传excel_判断浏览器

二、实现文件上传:

2.1. upload.jsp页面的代码如下:
upload.jsp页面的代码如下:

<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <script type="text/javascript">
        function addFile(){
            var div = document.getElementById("files");
            div.innerHTML+="<div>文件:<input type='file' name='file'/><input type='button' value='删除' onclick='deleteFile(this)'/></div>";
        }

        function deleteFile(bt){
            var div = document.getElementById("files");
            div.removeChild(bt.parentNode);
        }
    </script>
  </head>

  <body>
  <center>
    <h1>邮件发送页面</h1>
    <!-- 上传的方式只能为post,因为只有post才能发流 -->
    <form action="upload" method="post" enctype="multipart/form-data">
        <table width="50%">
            <tr>
                <td width="15%">邮件主题</td><td><input type="text" name="info"/></td>
            </tr>

            <tr>
                <td>邮件附件</td><td><input type="button" value="添加附件" onclick="addFile()"/></td>
            </tr>
            <tr>
                <td colspan="2">
                <div id="files"></div>
                </td>
            </tr>

            <tr><td colspan="2"><input type="submit" value="提交"/></td></tr>
        </table>
    </form>
    </center>
  </body>
</html>

message.jsp页面的代码如下:

<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">

    <title>My JSP 'res.jsp' starting page</title>
  </head>
  <body>
    ${msg}
  </body>
</html>

2.2. 处理文件上传的Servlet
 UploadServlet的代码如下:

package com.bright;

import java.io.*;
import java.util.*;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import javax.ws.rs.core.Request;

import org.apache.commons.fileupload.*;
import org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.IOUtils;

public class UploadServlet extends HttpServlet {

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

    public void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        //准备工作
        req.setCharacterEncoding("utf-8");

        //得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全
        String path=this.getServletContext().getRealPath("/uploads");

        String temp=this.getServletContext().getRealPath("/temp");//设置一个临时目录
        String msg="";//定义提示信息

        //1、创建上传组件的工厂类
        DiskFileItemFactory factory=new DiskFileItemFactory();

        //setSizeThreshold方法用于设置是否将上传文件已临时文件的形式保存在磁盘的临界值(以字节为单位的int值),如果从没有调用该方法设置此临界值,将会采用系统默认值10KB
        factory.setSizeThreshold(1024*1024);//缓冲区大小为1M

        //setRepositoryPath方法用于设置当上传文件尺寸大于setSizeThreshold方法设置的临界值时,将文件以临时文件形式保存在磁盘上的存放目录
        factory.setRepository(new File(temp));

        //2、获取上传组件
        ServletFileUpload upload=new ServletFileUpload(factory);
        upload.setSizeMax(1024*1024*10);//上传文件最大为10M

        //设置监听器,可以监听上传的进度
        MyProgress listen=new MyProgress();
        upload.setProgressListener(listen);

        //3、创建一个文件上传解析器 从request得到所有上传域的列表
        try {
            //FileItem对象里面封装的数据是一个普通文本表单字段或者一个文件表单字段
            List<FileItem> list=upload.parseRequest(req);

            //4、遍历集合
            Iterator<FileItem> it=list.iterator();

            while(it.hasNext())
            {
                //5、取出表单中的数据放到FileItem中
                FileItem item=it.next();

                //6、判断你是否是文件如果是普通文本表单字段,返回一个true否则返回一个false
                if(item.isFormField())
                {
                    //不是文件 getFieldName方法用来返回表单标签的name属性的值。getString()方法将FileItem对象中保存的数据流内容以一个字符串返回
                    System.out.println(item.getFieldName()+"--"+item.getString());
                }else
                {
                    //是文件
                    //7、上传文件
                    String filename=item.getName();//文件名
                    InputStream in=item.getInputStream();//以流的形式返回上传文件的主体内容。

                    //8、将输入流通过输出流写到服务器的硬盘上
                    /*
                     * 文件名一般由程序生成 UUID 生成一个唯一的字符串作为名字
                     * 目录:根据日期来分散存放以日期命名的文件夹中
                     * 
                     * 存入数据库
                     *  ID,UUIDfile(服务器硬盘上的文件名),fileName(上传的时候叫什么名字),uploadtime,info...
                     */
                    File file=new File(path, filename);
                    OutputStream out=new FileOutputStream(file);

                    //9、将输入流的内容复制到输出流中使用IOUtils
                    IOUtils.copy(in, out);

                    //10、关闭流
                    in.close();
                    out.close();
                }

            }
            msg="恭喜你上传成功!!";

        } catch (FileSizeLimitExceededException e) {
            e.printStackTrace();
            msg="上传失败,最大只能传10M<a href='index.jsp'>重新上传</a>";

        }catch(Exception e){
            e.printStackTrace();
            msg="对不起,上传失败!<a href='index.jsp'>重新上传</a>";
        }
        req.setAttribute("msg", msg);

        /*实现请求转发的,当请求进入到该servlet中执行到该语句时,服务器不会直接响应而是转发到转发路径得servlet继续处理,由于将req和resp带过去了,所以这期间是没有重新创建request和response对象,
         * 所以在接下来的servlet中同样可以获得当前servlet的request中的参数。
         * */
        req.getRequestDispatcher("/res.jsp").forward(req, resp);
    }
}

在Web.xml文件中注册UploadServle

文件上传成功之后,上传的文件保存在了WEB-INF目录下的uploads目录,如下图所示:

2.3. 运行效果

jsp springboot上传excel_io流_02


jsp springboot上传excel_判断浏览器_03

2.4. 上传时的一些细节
2.4.1. 为保证服务器安全,上传文件应该放在外界无法直接访问的目录下,比如放于WEB-INF目录下。

2.4.2. 为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名。

2.4.3. 在表单中设置 enctype=”multipart/form-data”

2.4.4. 要限制上传文件的最大值。

2.4.5. 要限制上传文件的类型,在收到上传文件名时,判断后缀名是否合法。

三、实现文件下载:

3.0. 准备工作:要先有存在的文件

jsp springboot上传excel_jsp_04

3.1. 展示下载文件的download.jsp页面如下:

<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">

    <title>My JSP 'DownLoad.jsp' starting page</title>

  </head>

  <body>
  <!-- 在tomcat\apache-tomcat-7.0.65\webapps\jspday05\uploads下面要先存在需要下载的文件 -->
  <!-- 链接中要有文件的后缀名 -->
    <h3>文件下载</h3>
     <a href="download?filename=aaa.txt">aaa.txt</a><br/>
     <a href="download?filename=图书管理系统.docx">图书管理系统.docx</a><br/>
  </body>
</html>

3.2. DownLoadServlet的代码如下:

package com.bright;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.net.URLEncoder;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;

import sun.misc.BASE64Encoder;

public class DownLoadServlet extends HttpServlet {

    public void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        //1、获取文件的信息
        String filename=req.getParameter("filename");
        System.out.println(filename);

        //2、用get传输时处理乱码问题,utf-8是页面上数据传输的格式,iso-8859-1是你java项目格式,目的是为了将中文文件名正确显示在页面上。
        //filename=new String(filename.getBytes("iso-8859-1"),"utf-8");

        //3、创建一个文件,把你读到的数据写进这个文件中
        String path=this.getServletContext().getRealPath("/uploads");
        InputStream in=new FileInputStream(new File(path,filename));

        //4、判断用户用的是什么浏览器在下载(并未区分)
        String useage=req.getHeader("User-Agent");
        if(useage.indexOf("MSIE")>0)
        {
            //是IE浏览器
            System.out.println("是IE");

            //处理中文乱码问题
            filename = URLEncoder.encode(filename,"UTF-8");     

        }else{
            //其他浏览器
            System.out.println("其他浏览器");
            BASE64Encoder base64Encoder = new BASE64Encoder();
            filename = "=?utf-8?B?"+base64Encoder.encode(filename.getBytes("utf-8"))+"?=";
            System.out.println(filename);
        }

        //5、设置为下载application/x-download
        resp.setContentType("application/x-msdownload");        

        //6、文件下载,指定默认名
        resp.addHeader("Content-Disposition","attachment;filename=" + filename);  

        //7、向浏览器输出流对象
        OutputStream out=resp.getOutputStream();

        //8、将输入流中的内容复制到输出流中
        IOUtils.copy(in, out);

        //9、关闭流
        in.close();
        out.close();
    }


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

3.3. 运行效果:

jsp springboot上传excel_java_05


jsp springboot上传excel_jsp_06

3.4. 细节:
3.4.1. <a href="download?filename=aaa.txt">aaa.txt</a><br/>文件名要有后缀

3.4.2. 在下载时要判断浏览器:

IE浏览器:使用URL编码

jsp springboot上传excel_io流_07

其他浏览器,使用BASE64编码

jsp springboot上传excel_java_08

3.4.3. 将输入流中的内容复制到输出流中:

IOUtils.copy(in, out);

三、在web,xml中的配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  <display-name></display-name>
  <servlet>
    <servlet-name>UploadServlet</servlet-name>
    <servlet-class>com.bright.UploadServlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>DownLoadServlet</servlet-name>
    <servlet-class>com.bright.DownLoadServlet</servlet-class>
  </servlet>


  <servlet-mapping>
    <servlet-name>UploadServlet</servlet-name>
    <url-pattern>/upload</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>DownLoadServlet</servlet-name>
    <url-pattern>/download</url-pattern>
  </servlet-mapping>    
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>