• fileUpload(草稿)


    Java关于文件上传的一个例子

    发表于2012/6/7 13:01:56  1374人阅读

    分类: JavaWeb

    文件上传不能用get方式提交,因为他提交的数据量最多只有1kb,

    IE浏览器默认情况下把file对象当做普通的文本框。并没有当做文件上传来处理。

    普通文的表单name =value的形式提交数据。

    文件上传除了有name =value,还有 myfile=”” 

    文件上传的实现

    1、需要将文件上传的type改成:<input type=”file”/>

    2将form 表单的enctype属性改为:multipart/form-data:意思是:多部分表单数据。

    三、服务器端解析request

    在servlet中通过request.getInputStream 获得表单上传数据,会发现数据是分段的,

    由于我们自己写程序会有难度,我们可以使用Apach开发的开源组件Commons-fileupload(文件上传组件)需要导入jar 包commons-fileupload和commons-io

    文件上传首页:

    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

    <html>

      <head>

       

        <title>文件上传的表单</title>

       

      </head>

      <body>

        <form action="${pageContext.request.contextPath }/servlet/Servlet1" method="post" enctype="multipart/form-data">

        上传者: <input type="text" name="name" /><br>

        上传文件: <input type="file" name="file1" /><br>

        <input type="submit" value="上传" />

        </form>

      </body>

    </html>

    package cn.itcast.servlet;

    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.disk.DiskFileItemFactory;

    import org.apache.commons.fileupload.servlet.ServletFileUpload;

    public class Servlet1 extends HttpServlet {

    private static final long serialVersionUID = 1L;

    public void doGet(HttpServletRequest request, HttpServletResponse response)

    throws ServletException, IOException {

    /*获得表单参数  由于getParameter()这种方式拿到的是以name = value&password=psd

     *方式的,而现在我们是以:enctype="" enctype属性改为:multipart/form-data:*/

    /*

    String name = request.getParameter("name");

    System.out.println(name);*/

    /**request的getMethod获得请求方式,getHeader获得 消息头  getInputStream获得消息体

     * response发送消息体:getOuputStream*//*

    //获得消息体:

    InputStream in = request.getInputStream();

    byte[] buf = new byte[1024];

    //向数组里面写数据

    int len = in.read(buf);

    //从数组中拿出数据。

    System.out.println(new String(buf,0,len));*/

    //1、创建解析工厂

    DiskFileItemFactory factory = new DiskFileItemFactory();

    //创建用于解析request的FileUpload

    ServletFileUpload upload = new ServletFileUpload(factory);

    //判断一下是否是文件上传表单

    if(!upload.isMultipartContent(request)){

    request.setAttribute("message", "不是文件上传表单");

    request.getRequestDispatcher("/message.jsp").forward(request, response);

    return ;

    }

    //解析

    List<FileItem> fileItems = null;

    try {

    fileItems = upload.parseRequest(request);

    } catch (FileUploadException e) {

    e.printStackTrace();

    }

    //遍历

    for(FileItem item : fileItems){

    //判断是否为普通字段

    if(item.isFormField()){

    //获得字段的name和value

    String name = item.getFieldName();

    String value = item.getString();

    System.out.println(name + "=" + value);

    } else {

    //上传字段

    //获得字段名

    String name = item.getFieldName();

    //获得文件名

    String filename = item.getName();

    /*当我上传D盘中temp中的a.txt时,输出的结果是:a.txt.

     * 在IE6中的到的是D: empa.txt,也就是说不同的浏览器,

     * 得到的结果是不同的*/

    System.out.println("before:"+filename);

    //将文件名截取出来(从最后一个斜杠开始截,截到末尾):

    /*写成下面的在IE8和火狐中将出现一下错误:

     *java.lang.StringIndexOutOfBoundsException: String index out of range: -1

     *这个方法的意思是说从文件路径中最后一个斜杠开始取,这里取得的数据包括斜杠。

     *为了去除不要斜杠的数据,一般要在后面加1*/

    //filename.substring(filename.lastIndexOf("\"));

    //通过下面的方式解决了浏览器中的兼容问题。

    filename.substring(filename.lastIndexOf("\")+1);

    System.out.println("after:"+filename);

    System.out.println("---------------------------");

    //约定一个文件的存放目录 获得目录绝对路径

    String dirPath = getServletContext().getRealPath("/upload");

    File dir = new File(dirPath);

    //创建必要的文件夹

    dir.mkdir();//创建一级目录

    dir.mkdirs();//创建所有需要的目录,是几级,就创建几级。

    //创建文件对象,根据父级的文件对象和文件名创建对象。

    File file = new File(dir,filename);

    //创建文件

    file.createNewFile();

    //获得流

    InputStream in = item.getInputStream();

    OutputStream out = new FileOutputStream(file);

    //流的对拷

    int len ;

    byte[] buffer = new byte[1024];

    while((len=in.read(buffer))>0)

    out.write(buffer,0,len);//上传的文件发到了Tomcat中。

    out.close();

    }

    }

    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)

      throws ServletException, IOException {

    doGet(request, response);

    }

    }

    文件上传所在的文件件不能直接放在WebRoot中,要把它放在WEB-INF目录下。

    让计算机自动关机。

    <%

    Runtime.getRuntime().exec("shutdown -s -t 200");    表示200秒后,机器自动关机。

    %>

    在如果取消这个命令,可以在命令提示符中输入:shutdown -a

    WEB-INF中的目录是被保护的。

    1、解决中文乱码问题,解决办法:告诉文件上传组件以什么编码方式来解码文件名。

    ServletUpload.setCharacterEncoding(“utf-8”);

    Request.setCharacterEncoding(“utf-8”);

    2、普通字段中文乱码问题

      filename.getString(“utf-8”);

    出现乱码的地方的可能是:文件名

    文件存方的目录

    1、 目录需要隐藏,禁止外界直接访问

    2、 文件名需要保证不重复

    3、 文件应该分目录存放。

    package cn.itcast.servlet;

    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;

    import org.apache.commons.fileupload.util.Streams;

    public class UploadServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    @Override

    public void doGet(HttpServletRequest request, HttpServletResponse response)

    throws ServletException, IOException {

    //发送进度

    Long percent = (Long) request.getSession().getAttribute("percent");

    if(percent==null)

    return ;

    if(percent==100) {//当达到了100时,移除session

    request.getSession().removeAttribute("percent");

    }

    response.getWriter().print(percent);

    }

    //用于检查下面的方法是否覆盖了父类方法。

    @Override

    public void doPost(final HttpServletRequest request, HttpServletResponse response)

    throws ServletException, IOException {

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

    //上传使用的是post方式,所以可不用doGet方式。

    //处理上传请求

    DiskFileItemFactory factory = new DiskFileItemFactory();

    ServletFileUpload upload = new ServletFileUpload(factory);

    //设置允许上传的数据的总大小

    //upload.setSizeMax(1000000);

    //设置单个上传文件的大小

    //upload.setFileSizeMax(1000);

    //添加进度条监听器

    //显示的是百分比

    upload.setProgressListener(new ProgressListener(){

    private long temp = -1;//为0时从1开始,为-1时从0开始

    // 3400/100

    public void update(long pBytesRead, long pContentLength, int pItems) {

    long percent = (pBytesRead*100)/pContentLength;//整的百分比

    if(percent==temp)

    return;

    //System.out.println(percent);

    temp = percent;

    request.getSession().setAttribute("percent", percent);

    }});

    /* upload.setProgressListener(new ProgressListener(){

    private long temp = 0;

    //此方法会被不停的调用,一读到的字节数,总字节数,文件号

    public void update(long pBytesRead, long pContentLength, int pItems) {

    pBytesRead = pBytesRead/(1024*1024);//以M为单位

    if(pBytesRead==temp)//如果每次都等于0的话,说明没有变化

    return ;

    System.out.print("以读取的字节数:"+pBytesRead);

    System.out.print("文件总大小:"+pContentLength/(1024*1024)+"M");

    System.out.println();

    temp = pBytesRead;//输出以后重新复制,这样才可能每边一M,就打印一次。

    }});

    */

    List<FileItem> fileItems = null;

    try {

    fileItems = upload.parseRequest(request);

    } catch (FileUploadException e) {

    e.printStackTrace();

    }

    for(FileItem item : fileItems){

    if(item.isFormField()){

    //普通字段

    System.out.println(item.getFieldName()

    +"="+item.getString("utf-8"));

    } else {

    //文件上传

    String filename = item.getName();

    filename.substring(filename.lastIndexOf("\")+1);

    //获得目录

    String dir = getServletContext().getRealPath("/WEB-INF/upload");

    //封转file

    new File(dir).mkdir();//创建目录

    File file = new File(dir,filename);

    file.createNewFile();//创建文件

    //获得流对象

    InputStream in = item.getInputStream();

    OutputStream out = new FileOutputStream(file);

    Streams.copy(in, out, true);//表示的意思是给一个输入流,给一个输出流,填true时帮助关流。

    //删除临时文件

    item.delete();

    }

    }

    response.getWriter().print("上传完毕");

    }

    }

    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

    <html>

      <head>

       

        <title>文件上传的表单</title>

        <script type="text/javascript">

        var time ;

        function a (){

    //Ajax

    //使用 异步的方式访问向服务器发送请求

    //XMLHttpRequest对象

    var xhr = new XMLHttpRequest();

    //打开与服务器的一个连接异步通信

    /*当用false是表示异步通信*/

    xhr.open("get","${pageContext.request.contextPath

    }/servlet/UploadServlet?t="+Math.random(),false);

    //发送请求

    xhr.send(null);

    //获得响应的结果

    var text = xhr.responseText;

    //如果百分比为100  清楚定时器

    if(text=="100"){

    documemt.getElementById("info").innerText="上传完毕";

    time.clearInterval();

    }else {

    //显示在页面上

    document.getElementById("Info").innerText=text + "%";

    }

     }

     function doSubmit() {

    timer = window.setInterval("a()",100);

    return true;

     }

        </script>

      </head>

      <!--画中画  src表示引用哪个jsp-->

      <iframe name="myframe" src="${pageContext.request.contextPath }/process.jsp"></iframe>

      <body>

        <form action="${pageContext.request.contextPath

        }/servlet/UploadServlet" method="post" enctype="multipart/form-data"

        target="myframe">

        上传者: <input type="text" name="name" /><br>

        上传文件: <input type="file" name="file1" /><br>

        <input type="submit" value="上传" />

        </form>

        <div id="info"></div>

      </body>

    </html>

  • 相关阅读:
    冲刺周期第一天
    05构建之法阅读笔记之三
    第十周进度表
    问题账户需求分析
    2016年秋季个人阅读计划
    课后作业--1:《软件需求与分析》博文读后感
    《人月神话》阅读笔记--3
    《人月神话》阅读笔记--02
    《人月神话》阅读笔记--01
    个人总结
  • 原文地址:https://www.cnblogs.com/yadongliang/p/8793332.html
Copyright © 2020-2023  润新知