javaEE:day7-上传文件(Apache包)、目录打散、文件上传进度条、纯前台进度条

用Apache工具做文件上传

1获得所接受文件要保存的路径

String path = getServletContext().getRealPath("/files");

2文件上传的临时目录,如不指定则为Tomcat/temps

File tempDir = new File("d:/a");

3创建用于解析文件的工厂类,同时设置缓冲区

注意这个类是Apache公司的jar包要导入两个jar包

        DiskFileItemFactory fileFactory = new DiskFileItemFactory(1024*8, tempDir);
        ServletFileUpload upload = new ServletFileUpload(fileFactory);

4设置每个上传文件最大值

upload.setFileSizeMax(1024*1024*5);

5设置所有上传文件大小的最大值

upload.setSizeMax(1024*1024*10);//10M

6开始解析–返回list集合

List<FileItem> list =  upload.parseRequest(request);

7分流:分为一般表单文件和上传文件

            if(item.isFormField()){//一般表单组件
                    String str = item.getString("utf-8");//以指定编码方式接受,以解决普通表单组件接受中文乱码
                    System.out.println("普通表单组件..."+str);
                }else{//文件组件

                }

8文件上传,文件拷贝

    FileUtils.copyInputStreamToFile(item.getInputStream(), new File(path+"/"+fileName2));

小细节:

服务器中文件名不能用中文,而且文件名又要唯一所以我们用UUID来做

                    String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                    String ext = fileName.substring(fileName.lastIndexOf("."));
                    String fileName2 = uuid+ext;

防黑处理1 在地址栏直接提交 ,则输出你请求的页面不支持get…

public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //防黑处理1 在地址栏直接提交 ,则输出你请求的页面不支持get...
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().print("你请求的页面不支持此方式提交...");
    }

对于response.setContentType("text/html;charset=utf-8"); 而言如果是“multipart/form-data”表单,可以设置其中file组件的文件名,但对其中的普通表单组件无效。如果是我们以前用的“application/x-www-form-urlencoded”表单,可以设置其中的普通表单组件。

防黑2 非“multipart/form-data”表单提交

//法1: 手动解决
        String type = request.getContentType();
        if(!type.contains("multipart/form-data")){
            response.getWriter().print("此中提交方式不支持...");
            return;
        }
        //法2:使用上传工具解决
        boolean boo = ServletFileUpload.isMultipartContent(request);
        if(!boo){
            response.getWriter().print("此中提交方式不支持...");
            return;
        }

对于一般表单组件,以指定编码方式接受,以解决普通表单组件接受中文乱码

String str = item.getString("utf-8");

目录打散

目录打散我们是借助于fileName.hashCode 取每后四位做一层目录。16*16的目录方式来做。

                    String dir1 = Integer.toHexString(fileName.hashCode() & 0xf);
                    String dir2 = Integer.toHexString((fileName.hashCode() & 0xf0)>>4);
                    File dir = new File(path+"/"+dir1+"/"+dir2);
                    if(!dir.exists()){
                        dir.mkdirs();
                    }
                    File file = new File(dir+"/"+fileName2);

文件上传进度条简易版

用监听器监听,过多久刷一次。

upload.setProgressListener(new ProgressListener() {
            private int p=0;
            //readedBytes:已上传字节数   countBytes:上传的总字节数   count:文件序号(从1开始的)
            @Override
            public void update(long readedBytes, long countBytes, int count) {
                double d = readedBytes * 100.0 /countBytes;
                int dd = (int) d;
                if( dd != p ){
                    out.print("当前进度:"+dd+"<br/>");
                    p = dd;
                }
            }
        });

纯前台进度条

用两个div来做,通过JavaScript来设置里面那个div的width。

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <script type="text/javascript">
        function start(){
            a=0;
            time =  window.setInterval(run, 1000);
        }
        var a=0;
        function run(){
            a+=10;
            if(a>100){
                window.clearInterval(time);
                return;
            }
            var div = document.getElementById("divPro");
            div.style.width = a+"%";
        }
        function stop(){
            window.clearInterval(time);
        }
        function resume(){
            window.clearInterval(time);
            time =  window.setInterval(run, 1000);
        }

    </script>
  </head>

  <body>
        <h2>进度条演示</h2>
        <div style="border: 2px solid green; width: 300px;height: 30px; ">
            <div id="divPro" style="background:red; width:30%; height:100%"></div>
        </div>
        <button onclick="start()">启动</button>
        <button onclick="stop()">停止</button>
        <button onclick="resume()">恢复</button>
  </body>
</html>

本文完整代码如下:

index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="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>
        <title>演示request和response用法</title>
  </head>
  <body>
  <!--通过request.getContextPath()可以把项目根目录(项目名)写活  -->
        <form action="<%=request.getContextPath() %>/requestDemo" method="post">
            姓名:<input type="text" name="name" /><br/>
            <input type="submit" value="提交"/>
        </form>
        <!-- 演示表单参数的接受 -->
        <form action="<%=request.getContextPath() %>/param" method="post">
            姓名:<input type="text" name="name" /><br/>
            年龄:<input type="text" name="age" /><br/>
            <input type="checkbox" name="hoby" value="music" />音乐&nbsp;&nbsp;
            <input type="checkbox" name="hoby" value="tv" />电视&nbsp;&nbsp;
            <input type="checkbox" name="hoby" value="game" />游戏<br/>
            <input type="radio" name="sex" value="0" checked="checked" >男&nbsp;&nbsp;
            <input type="radio" name="sex" value="1"><input type="submit" value="提交"/>
        </form>
        <!-- 演示文件上传 -->
        <h2>文件上传手动版</h2>
        <form action="<%=request.getContextPath() %>/upload1" method="post" enctype="multipart/form-data"> 
            文件名:<input type="file" name="fileName">
            <input type="submit" value="上传">
        </form>
        <!-- 上面这种手动上传 的方法不好。要自己解析,麻烦,我们用阿帕奇公司-Commons-io.jar 和 Commos-fileupload.jar写好的去做文件上传 -->

        <!-- 以下演示使用Apache公司的工具做上传 -->
        <h1>以下演示使用Apache公司的工具做上传  单项文件上传</h1>
        <form action="<%=request.getContextPath() %>/upload2" method="post" enctype="multipart/form-data"> 
            文件名:<input type="file" name="fileName">
            <input type="submit" value="上传">
        </form>
        <form action="<%=request.getContextPath() %>/upload2" method="post" enctype="multipart/form-data"> 
            文件1:<input type="file" name="fileName">
            文件1的说明:<input type="text" name="desc1">
            文件2:<input type="file" name="fileName2">
            文件2的说明:<input type="text" name="desc2">
            <input type="submit" value="上传">
        </form>
        <br/>
        <br/>
        <h1>完整点的文件上传</h1>
        <form action="<%=request.getContextPath() %>/upload3" method="post" enctype="multipart/form-data"> 
            文件1:<input type="file" name="fileName">
            文件1的说明:<input type="text" name="desc1">
            文件2:<input type="file" name="fileName2">
            文件2的说明:<input type="text" name="desc2">
            <input type="submit" value="上传">
        </form>
        <br/><br/>
        <a href = "progress.jsp">纯前台的进度条</a>

  </body>
</html>

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>RequestDemo</servlet-name>
    <servlet-class>cn.hncu.servlets.RequestDemo</servlet-class>
    <init-param>
        <param-name>name</param-name>
        <param-value>Hello</param-value>
    </init-param>
  </servlet>
  <servlet>
    <servlet-name>ParamerServlet</servlet-name>
    <servlet-class>cn.hncu.servlets.ParamerServlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>UpFileServlet</servlet-name>
    <servlet-class>cn.hncu.servlets.UpFileServlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>UploadServlet</servlet-name>
    <servlet-class>cn.hncu.servlets.upload.UploadServlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>UpLoadServlet3</servlet-name>
    <servlet-class>cn.hncu.servlets.upload.UpLoadServlet3</servlet-class>
  </servlet>





  <servlet-mapping>
    <servlet-name>RequestDemo</servlet-name>
    <url-pattern>/requestDemo</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>ParamerServlet</servlet-name>
    <url-pattern>/param</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>UpFileServlet</servlet-name>
    <url-pattern>/upload1</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>UploadServlet</servlet-name>
    <url-pattern>/upload2</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>UpLoadServlet3</servlet-name>
    <url-pattern>/upload3</url-pattern>
  </servlet-mapping>    
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

UploadServlet

package cn.hncu.servlets.upload;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.UUID;

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

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 org.apache.commons.io.FileUtils;

public class UploadServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //防黑处理1 在地址栏直接提交 ,则输出你请求的页面不支持get...
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().print("你请求的页面不支持此方式提交...");
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");

        //注意,下面这句设置中文,如果是“multipart/form-data”表单,可以设置其中file组件的文件名,但对其中的普通表单组件无效。
        //注意,下面这句设置中文,如果是我们以前用的“application/x-www-form-urlencoded”表单,可以设置其中的普通表单组件。
        response.setContentType("text/html;charset=utf-8");
        //1上传文件的保存路径
        String path = getServletContext().getRealPath("/files");

        //防黑2 非“multipart/form-data”表单提交
        //法1: 手动解决
//      String type = request.getContentType();
//      if(!type.contains("multipart/form-data")){
//          response.getWriter().print("此中提交方式不支持...");
//          return;
//      }
        //法2:使用上传工具解决
        boolean boo = ServletFileUpload.isMultipartContent(request);
        if(!boo){
            response.getWriter().print("此中提交方式不支持...");
            return;
        }



        //2文件上传的临时目录,如不指定则为tomcat/temps
        File tempDir = new File("d:/a");
        //3创建用于解析文件的工厂类,同时设置缓冲区大小和位置
        DiskFileItemFactory fileFactory = new DiskFileItemFactory(1024*8, tempDir);
        ServletFileUpload upload = new ServletFileUpload(fileFactory);
        //4设置每个文件的最大值
        upload.setFileSizeMax(1024*1024*5);
        //5设置所有文件大小之和的最大值
        upload.setSizeMax(1024*1024*10);//10M
        //6开始解析request--->返回list集合
        try {
            List<FileItem> list =  upload.parseRequest(request);
            //7分流:分为文件组件和一般表单组件
            for(FileItem item : list) {
                if(item.isFormField()){//一般表单组件
                    String str = item.getString("utf-8");//以指定编码方式接受,以解决普通表单组件接受中文乱码
                    System.out.println("普通表单组件..."+str);
                }else{//文件组件
                    //防黑3 用户不选择文件提交
                    if(item.getSize()==0){
                        continue;
                    }
                    //文件名
                    String fileName = item.getName();
                    //服务器中名字不能用中文,但是文件名又要唯一我们用UUID来做
                    System.out.println("上传文件为:"+fileName);
                    String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                    String ext = fileName.substring(fileName.lastIndexOf("."));
                    String fileName2 = uuid+ext;
//                  System.out.println(path);
//                  System.out.println(fileName2);
                    //Apache公司自己帮我们做好了写文件的工具
                    //真正的文件内容在 item.getInputStream() 当中
                    FileUtils.copyInputStreamToFile(item.getInputStream(), new File(path+"/"+fileName2));
                }
            }
        } catch (FileUploadException e) {
            e.printStackTrace();
        }
    }

}

UpLoadServlet3

package cn.hncu.servlets.upload;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.UUID;

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

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

public class UpLoadServlet3 extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //防黑处理1 在地址栏直接提交 ,则输出你请求的页面不支持get...
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().print("你请求的页面不支持此方式提交...");
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        //注意,下面这句设置中文,如果是“multipart/form-data”表单,可以设置其中file组件的文件名,但对其中的普通表单组件无效。
        //注意,下面这句设置中文,如果是我们以前用的“application/x-www-form-urlencoded”表单,可以设置其中的普通表单组件。
        response.setContentType("text/html;charset=utf-8");
        final PrintWriter out = response.getWriter();
        //1上传文件的保存路径
        String path = getServletContext().getRealPath("/files");

        //防黑2 非“multipart/form-data”表单提交
        //法1: 手动解决
//      String type = request.getContentType();
//      if(!type.contains("multipart/form-data")){
//          response.getWriter().print("此中提交方式不支持...");
//          return;
//      }
        //法2:使用上传工具解决
        boolean boo = ServletFileUpload.isMultipartContent(request);
        if(!boo){
            response.getWriter().print("此中提交方式不支持...");
            return;
        }



        //2文件上传的临时目录,如不指定则为tomcat/temps
        File tempDir = new File("d:/a");
        //3创建用于解析文件的工厂类,同时设置缓冲区大小和位置
        DiskFileItemFactory fileFactory = new DiskFileItemFactory(1024*8, tempDir);
        ServletFileUpload upload = new ServletFileUpload(fileFactory);
        //4设置每个文件的最大值
        upload.setFileSizeMax(1024*1024*5);
        //5设置所有文件大小之和的最大值
        upload.setSizeMax(1024*1024*10);//10M

        //文件上传进度条基础版
        upload.setProgressListener(new ProgressListener() {
            private int p=0;
            //readedBytes:已上传字节数   countBytes:上传的总字节数   count:文件序号(从1开始的)
            @Override
            public void update(long readedBytes, long countBytes, int count) {
                double d = readedBytes * 100.0 /countBytes;
                int dd = (int) d;
                if( dd != p ){
                    out.print("当前进度:"+dd+"<br/>");
                    p = dd;
                }
            }
        });



        //6开始解析request--->返回list集合
        try {
            List<FileItem> list =  upload.parseRequest(request);
            //7分流:分为文件组件和一般表单组件
            for(FileItem item : list) {
                if(item.isFormField()){//一般表单组件
                    String str = item.getString("utf-8");//以指定编码方式接受,以解决普通表单组件接受中文乱码
                    System.out.println("普通表单组件..."+str);
                }else{//文件组件
                    //防黑3 用户不选择文件提交
                    if(item.getSize()==0){
                        continue;
                    }
                    //文件名
                    String fileName = item.getName();
                    fileName = fileName.substring(fileName.lastIndexOf("/")+1);
                    //服务器中名字不能用中文,但是文件名又要唯一我们用UUID来做
                    System.out.println("上传文件为:"+fileName);
                    String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                    String ext = fileName.substring(fileName.lastIndexOf("."));
                    String fileName2 = uuid+ext;

                    //打散目录
                    String dir1 = Integer.toHexString(fileName.hashCode() & 0xf);
                    String dir2 = Integer.toHexString((fileName.hashCode() & 0xf0)>>4);
                    File dir = new File(path+"/"+dir1+"/"+dir2);
                    if(!dir.exists()){
                        dir.mkdirs();
                    }
                    File file = new File(dir+"/"+fileName2);

//                  System.out.println(path);
//                  System.out.println(fileName2);
                    //Apache公司自己帮我们做好了写文件的工具
                    //真正的文件内容在 item.getInputStream() 当中
                    //FileUtils.copyInputStreamToFile(item.getInputStream(), new File(path+"/"+fileName2));
                    try {
                        item.write(file);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                }
            }
        } catch (FileUploadException e) {
            e.printStackTrace();
        }
    }

}

progress.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <script type="text/javascript">
        function start(){
            a=0;
            time =  window.setInterval(run, 1000);
        }
        var a=0;
        function run(){
            a+=10;
            if(a>100){
                window.clearInterval(time);
                return;
            }
            var div = document.getElementById("divPro");
            div.style.width = a+"%";
        }
        function stop(){
            window.clearInterval(time);
        }
        function resume(){
            window.clearInterval(time);
            time =  window.setInterval(run, 1000);
        }

    </script>
  </head>

  <body>
        <h2>进度条演示</h2>
        <div style="border: 2px solid green; width: 300px;height: 30px; ">
            <div id="divPro" style="background:red; width:30%; height:100%"></div>
        </div>
        <button onclick="start()">启动</button>
        <button onclick="stop()">停止</button>
        <button onclick="resume()">恢复</button>
  </body>
</html>
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值