JAVA文件上传 ServletFileUpLoad 实例

1.  jsp

<%@ page language="java" contentType="text/html" pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<title>文件上传</title>
</head>
<body>
    <form action="FileUploadServlet" method="post" enctype="multipart/form-data">
        用户名:<input type="text" name="name"><br>
        文件1:<input type="file" name="f1"><br>
        文件2:<input type="file" name="f2"><br>
        <input type="submit" value="提交">
    </form>
    
</body>
</html>

2.  java  

文件上传的前提
 1.form表单的method必须是post
 2.form表单的enctype必须是multipart/form-data 以二进制字节流
 进行提交 传统接收参数的方式无效
 DiskFileItemFactory:环境
     void setSizeThreshold(int sizeThreshold)
     设置缓冲区大小,默认10KB 超出将使用临时文件上传
     void setRepository(File repository)
     设置临时文件路径
 ServletFileUpload:核心操作类
     public void setSizeMax(long sizeMax)设置总文件的大小
     public void setFileSizeMax(long fileSizeMax):设置单个文件的大小
     public List parseRequest(javax.servlet.http.HttpServletRequest req)
     解析请求正文内容
     public static boolean isMultipartContent(HttpServletRequest req)//判断enctype
 FileItem:输入域
     boolean  isFormField():判断是否是普通字段
     String getName():获取上传文件名
     String getFieldName():获取普通字段的字段名
     String getString():获取普通字段的值
     String getContentType() 获得文件类型
     InputStream  getInputStream()以流的形式返回上传文件的主体内容
     void  delete()删除临时文件
 文件上传中需要注意的问题
    1.保证安全 
        上传文件放在WEB-INF目录中
    2.中文乱码问题
        普通字段乱码
        String fieldValue = item.getString("GBK");
          文件名乱码
          request.setCharacterEncoding("GBK");
      3.重名文件覆盖
          1.UUID
          2.使用文件上传日期分类存储
          3.System.currentMillions()
      4.限制文件上传类型
         1.endsWith("")这种方式不可取
         2.判断其mime类型 getContentType()
      5.限制用户上传文件的大小
          1.限制单个上传文件的大小
          upload.setFileSizeMax(4*1024*1024);
          2.限制总文件大小
        upload.setSizeMax()
     6.临时文件
         item.delete();
     7.多个文件上传时,没有上传内容的问题
         if(fileName==null||"".equals(fileName.trim())){
                        continue;
        }
     8.上传进度检测
            upload.setProgressListener(new ProgressListener(){
                参数一:已上传的字节数
                参数二:总字节数
                参数三:第几项
                @Override
                public void update(long arg0, long arg1, int arg2) {
                    // TODO Auto-generated method stub
                    System.out.println(arg0+"  "+arg1+"  "+arg2);
                }
                
            });
package cn.gs.ly;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

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;


public class FileUploadServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        try {
        //得到上传文件的保存目录。 将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全
        String realPath = this.getServletContext().getRealPath("/upload");//  /WEB-INF/files
        System.out.println("文件存放位置:"+realPath);
        //设置临时目录。 上传文件大于缓冲区则先放于临时目录中
        String tempPath = "E:\\tempPath";
        System.out.println("临时文件存放位置:"+tempPath);
        
        
        //判断存放上传文件的目录是否存在(不存在则创建)
        File f = new File(realPath);
            if(!f.exists()&&!f.isDirectory()){
                System.out.println("目录或文件不存在! 创建目标目录。");
                f.mkdir();
            }
        //判断临时目录是否存在(不存在则创建)
        File f1 = new File(tempPath);
            if(!f1.isDirectory()){
                System.out.println("临时文件目录不存在! 创建临时文件目录");
                f1.mkdir();
            }
        
       /**
        * 使用Apache文件上传组件处理文件上传步骤:
        * 
        * */
        //1、设置环境:创建一个DiskFileItemFactory工厂    
        DiskFileItemFactory factory = new DiskFileItemFactory();
        
            //设置上传文件的临时目录
        factory.setRepository(f1); 
        
        //2、核心操作类:创建一个文件上传解析器。
        ServletFileUpload upload = new ServletFileUpload(factory);
            //解决上传"文件名"的中文乱码
        upload.setHeaderEncoding("UTF-8");
        
        //3、判断enctype:判断提交上来的数据是否是上传表单的数据
        if(!ServletFileUpload.isMultipartContent(req)){
            System.out.println("不是上传文件,终止");
             //按照传统方式获取数据
            return;
        }
        
        //==获取输入项==
//            //限制单个上传文件大小(5M)
//            upload.setFileSizeMax(1024*1024*4);
//            //限制总上传文件大小(10M)
//            upload.setSizeMax(1024*1024*6);
        
        //4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项
            List<FileItem> items =upload.parseRequest(req);
            for(FileItem item:items){
                //如果fileitem中封装的是普通输入项的数据(输出名、值)
                if(item.isFormField()){
                    String filedName = item.getFieldName();//普通输入项数据的名
                    //解决普通输入项的数据的中文乱码问题
                    String filedValue = item.getString("UTF-8");//普通输入项的值
                    System.out.println("普通字段:"+filedName+"=="+filedValue);
                }else{
                    //如果fileitem中封装的是上传文件,得到上传的文件名称,        
                    String fileName = item.getName();//上传文件的名
                    //多个文件上传输入框有空 的 异常处理
                    if(fileName==null||"".equals(fileName.trim())){  //去空格是否为空
                        continue;// 为空,跳过当次循环,  第一个没输入则跳过可以继续输入第二个
                    }
                    
                    //注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如:  c:\a\b\1.txt,而有些只是单纯的文件名,如:1.txt
                    //处理上传文件的文件名的路径,截取字符串只保留文件名部分。//截取留最后一个"\"之后,+1截取向右移一位("\a.txt"-->"a.txt")
                    fileName = fileName.substring(fileName.lastIndexOf("\\")+1);
                    //拼接上传路径。存放路径+上传的文件名
                    String filePath = realPath+"\\"+fileName;
                    //构建输入输出流
                    InputStream in = item.getInputStream(); //获取item中的上传文件的输入流 
                    OutputStream out = new FileOutputStream(filePath); //创建一个文件输出流
                    
                    //创建一个缓冲区
                    byte b[] = new byte[1024];
                    //判断输入流中的数据是否已经读完的标识
                    int len = -1;
                     //循环将输入流读入到缓冲区当中,(len=in.read(buffer))!=-1就表示in里面还有数据
                    while((len=in.read(b))!=-1){  //没数据了返回-1
                    //使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath+"\\"+filename)当中
                        out.write(b, 0, len);
                    }
                    //关闭流
                    out.close();
                    in.close();
                    //删除临时文件
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    item.delete();//删除处理文件上传时生成的临时文件
                    System.out.println("文件上传成功");
                }    
            }    
        } catch (FileUploadException e) {
            //e.printStackTrace();
            throw new RuntimeException("服务器繁忙,文件上传失败");
        }    
    }
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

转自:https://www.cnblogs.com/liuyangv/p/8298997.html

  • 6
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
将Apache的commons-fileupload.jar放在应用程序的WEB-INF\lib下,即可使用。下面举例介绍如何使用它的文件上传功能。 所使用的fileUpload版本为1.2,环境为Eclipse3.3+MyEclipse6.0。FileUpload 是基于 Commons IO的,所以在进入项目前先确定Commons IO的jar包(本文使用commons-io-1.3.2.jar)在WEB-INF\lib下。 此文作示例工程可在文章最后的附件中下载。 示例1 最简单的例子,通过ServletFileUpload静态类来解析Request,工厂类FileItemFactory会对mulipart类的表单中的所有字段进行处理,不只是file字段。getName()得到文件名,getString()得到表单数据内容,isFormField()可判断是否为普通的表单项。 demo1.html <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=GB18030"> <title>File upload</title> </head> <body> //必须是multipart的表单数据。 <form name="myform" action="demo1.jsp" method="post" enctype="multipart/form-data"> Your name: <br> <input type="text" name="name" size="15"><br> File:<br> <input type="file" name="myfile"><br> <br> <input type="submit" name="submit" value="Commit"> </form> </body> </html> demo1.jsp <%@ page language="java" contentType="text/html; charset=GB18030" pageEncoding="GB18030"%> <%@ page import="org.apache.commons.fileupload.*"%> <%@ page import="org.apache.commons.fileupload.servlet.*"%> <%@ page import="org.apache.commons.fileupload.disk.*"%> <%@ page import="java.util.*"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <% boolean isMultipart = ServletFileUpload.isMultipartContent(request);//检查输入请求是否为multipart表单数据。 if (isMultipart == true) { FileItemFactory factory = new DiskFileItemFactory();//为该请求创建一个DiskFileItemFactory对象,通过它来解析请求。执行解析后,所有的表单项目都保存在一个List中。 ServletFileUpload upload = new ServletFileUpload(factory); List<FileItem> items = upload.parseRequest(request); Iterator<FileItem> itr = items.iterator(); while (itr.hasNext()) { FileItem item = (FileItem) itr.next(); //检查当前项目是普通表单项目还是上传文件。 if (item.isFormField()) {//如果是普通表单项目,显示表单内容。 String fieldName = item.getFieldName(); if (fieldName.equals("name")) //对应demo1.html中type="text" name="name" out.print("the field name is" + item.getString());//显示表单内容。 out.print("<br>"); } else {//如果是上传文件,显示文件名。 out.print("the upload file name is" + item.getName()); out.print("<br>"); } } } else { out.print("the enctype must be multipart/form-data"); } %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=GB18030"> <title>File upload</title> </head> <body> </body> </html> 结果: the field name isjeff the upload file name isD:\C语言考试样题\作业题.rar 示例2 上传两个文件到指定的目录。 demo2.html <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=GB18030"> <title>File upload</title> </head> <body> <form name="myform" action="demo2.jsp" method="post" enctype="multipart/form-data"> File1:<br> <input type="file" name="myfile"><br> File2:<br> <input type="file" name="myfile"><br> <br> <input type="submit" name="submit" value="Commit"> </form> </body> </html> demo2.jsp <%@ page language="java" contentType="text/html; charset=GB18030" pageEncoding="GB18030"%> <%@ page import="org.apache.commons.fileupload.*"%> <%@ page import="org.apache.commons.fileupload.servlet.*"%> <%@ page import="org.apache.commons.fileupload.disk.*"%> <%@ page import="java.util.*"%> <%@ page import="java.io.*"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <%String uploadPath="D:\\\\temp"; boolean isMultipart = ServletFileUpload.isMultipartContent(request); if(isMultipart==true){ try{ FileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(factory); List<FileItem> items = upload.parseRequest(request);//得到所有的文件 Iterator<FileItem> itr = items.iterator(); while(itr.hasNext()){//依次处理每个文件 FileItem item=(FileItem)itr.next(); String fileName=item.getName();//获得文件名,包括路径 if(fileName!=null){ File fullFile=new File(item.getName()); File savedFile=new File(uploadPath,fullFile.getName()); item.write(savedFile); } } out.print("upload succeed"); } catch(Exception e){ e.printStackTrace(); } } else{ out.println("the enctype must be multipart/form-data"); } %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=GB18030"> <title>File upload</title> </head> <body> </body> </html> 结果: upload succeed 此时,在"D:\temp"下可以看到你上传的两个文件。 示例3 上传一个文件到指定的目录,并限定文件大小。 demo3.html <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=GB18030"> <title>File upload</title> </head> <body> <form name="myform" action="demo3.jsp" method="post" enctype="multipart/form-data"> File:<br> <input type="file" name="myfile"><br> <br> <input type="submit" name="submit" value="Commit"> </form> </body> </html> demo3.jsp <%@ page language="java" contentType="text/html; charset=GB18030" pageEncoding="GB18030"%> <%@ page import="org.apache.commons.fileupload.*"%> <%@ page import="org.apache.commons.fileupload.servlet.*"%> <%@ page import="org.apache.commons.fileupload.disk.*"%> <%@ page import="java.util.*"%> <%@ page import="java.io.*"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <% File uploadPath = new File("D:\\temp");//上传文件目录 if (!uploadPath.exists()) { uploadPath.mkdirs(); } // 临时文件目录 File tempPathFile = new File("d:\\temp\\buffer\\"); if (!tempPathFile.exists()) { tempPathFile.mkdirs(); } try { // Create a factory for disk-based file items DiskFileItemFactory factory = new DiskFileItemFactory(); // Set factory constraints factory.setSizeThreshold(4096); // 设置缓冲区大小,这里是4kb factory.setRepository(tempPathFile);//设置缓冲区目录 // Create a new file upload handler ServletFileUpload upload = new ServletFileUpload(factory); // Set overall request size constraint upload.setSizeMax(4194304); // 设置最大文件尺寸,这里是4MB List<FileItem> items = upload.parseRequest(request);//得到所有的文件 Iterator<FileItem> i = items.iterator(); while (i.hasNext()) { FileItem fi = (FileItem) i.next(); String fileName = fi.getName(); if (fileName != null) { File fullFile = new File(fi.getName()); File savedFile = new File(uploadPath, fullFile .getName()); fi.write(savedFile); } } out.print("upload succeed"); } catch (Exception e) { e.printStackTrace(); } %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=GB18030"> <title>File upload</title> </head> <body> </body> </html> 示例4 利用Servlet来实现文件上传Upload.java package com.zj.sample; import java.io.File; import java.io.IOException; import java.util.Iterator; import java.util.List; 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.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; @SuppressWarnings("serial") public class Upload extends HttpServlet { private String uploadPath = "D:\\temp"; // 上传文件的目录 private String tempPath = "d:\\temp\\buffer\\"; // 临时文件目录 File tempPathFile; @SuppressWarnings("unchecked") public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { try { // Create a factory for disk-based file items DiskFileItemFactory factory = new DiskFileItemFactory(); // Set factory constraints factory.setSizeThreshold(4096); // 设置缓冲区大小,这里是4kb factory.setRepository(tempPathFile);// 设置缓冲区目录 // Create a new file upload handler ServletFileUpload upload = new ServletFileUpload(factory); // Set overall request size constraint upload.setSizeMax(4194304); // 设置最大文件尺寸,这里是4MB List<FileItem> items = upload.parseRequest(request);// 得到所有的文件 Iterator<FileItem> i = items.iterator(); while (i.hasNext()) { FileItem fi = (FileItem) i.next(); String fileName = fi.getName(); if (fileName != null) { File fullFile = new File(fi.getName()); File savedFile = new File(uploadPath, fullFile.getName()); fi.write(savedFile); } } System.out.print("upload succeed"); } catch (Exception e) { // 可以跳转出错页面 e.printStackTrace(); } } public void init() throws ServletException { File uploadFile = new File(uploadPath); if (!uploadFile.exists()) { uploadFile.mkdirs(); } File tempPathFile = new File(tempPath); if (!tempPathFile.exists()) { tempPathFile.mkdirs(); } } } demo4.html <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=GB18030"> <title>File upload</title> </head> <body> // action="fileupload"对应web.xml中<servlet-mapping>中<url-pattern>的设置. <form name="myform" action="fileupload" method="post" enctype="multipart/form-data"> File:<br> <input type="file" name="myfile"><br> <br> <input type="submit" name="submit" value="Commit"> </form> </body> </html> web.xml <servlet> <servlet-name>Upload</servlet-name> <servlet-class>com.zj.sample.Upload</servlet-class> </servlet> <servlet-mapping> <servlet-name>Upload</servlet-name> <url-pattern>/fileupload</url-pattern> </servlet-mapping>

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值