关于java中http上传组件Upload的使用

这篇博客介绍了如何使用Java的Upload组件处理HTTP文件上传。通过展示一个简单的HTML表单和对应的Servlet代码,说明了Upload Bean的使用方法。Upload类能够处理请求参数、文件上载,并设置保存目录、最大文件大小等属性。博主还提醒,此组件适用于JDK1.5及以上版本,且源代码在早期文章中已有分享。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对原来的Upload又重新用JDK1.5重写了一次.因为JDK已经发布1.6了,如果你还在用1.4,那你只好自己

根据我的思路翻译了.这个Bean最初是我在2002年写的(在此之前的文章当然是别人的原创),然后网上就出了

很多修改一些变量名,方法名或类名的各种版本,当然"版权"也就成了这些修改者的了.2002年我的原文在cnJBB

上,可以在那儿搜索到.

对这个Bean使用是非常简单.下面提供测试的代码.但愿意不再有人再问这个问题了.

html内容:

<form method="POST" action="http://localhost/servlet/debug.ServletTest?ccc=1&ccc=2" enctype="multipart/form-data">
<input type="text" name="aaa"><br/>
<input type="checkbox" name="bbb">b1<br/>
<input type="checkbox" name="bbb">b2<br/>
<input type="checkbox" name="bbb">b3<br/>
<br/>
<input type="file" name="filefeild"><br/>
<input type="file" name="filefeild"><br/>
<br/>
<input type="submit">
</form>

调用Bean的Servlet为:

    public void service(HttpServletRequest request, HttpServletResponse response) throws
            ServletException, IOException {
        response.setContentType(CONTENT_TYPE);
        PrintWriter out = response.getWriter();
        Upload up = new Upload();
        up.init(request);
           //在此之前request只能获取header,不能有获取实体的调用,即不能getInputStream或getParameter
        up.setSaveDir("d:/test/");
        up.setTagFileName("test.dat");//只对第一个文件起作用

        //这里可以设置其经属性.
        up.uploadFile();
        String aaa = up.getParameter("aaa");
        String[] bbb = up.getParameterValues("bbb");
        String[] ccc = up.getParameterValues("ccc");
       
        String[] fileName = up.getFileName();
        up.clear();
        System.out.println("aaa="+aaa);
        for(int i=0;i<bbb.length;i++)
            System.out.println("bbb="+bbb[i]);
        for(int i=0;i<ccc.length;i++)
            System.out.println("ccc="+ccc[i]);
        for(int i=0;i<fileName.length;i++)
            System.out.println(fileName[i]+":"+new File("d:/test/"+fileName[i]).exists());
        out.close();
    }

这个调用打印的结果为:

aaa=qqqq
bbb=on
bbb=on
bbb=on
ccc=1
ccc=2
test.dat.exe:true
daemon344.exe:true

 

 

 

下面是Upload.java:

 

package debug;

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.regex.*;
public class Upload {
  private String saveDir = ".";               //要保存文件的路径
  private String charset = "UTF-8";           //字符集

  private HashMap<String,ArrayList> parameter = new HashMap(); //存放参数名和值的数据结构
  private HttpServletRequest request;         //用于传入请求对象的实例
  private String boundary = "";               //内存数据的分隔符
  private int len = 0;                        //每次从内在中实际读到的字节长度
  private String queryString;
  private int count;                          //上载的文件总数
  private String[] fileName;                  //上载的文件名数组
  private long maxFileSize = 1024 * 1024 * 10; //最大文件上载字节;
  private String tagFileName = "";

  public final void init(HttpServletRequest request) throws ServletException {
    this.request = request;
    Matcher m = Pattern.compile("boundary=([//s//S]+)").matcher(request.getContentType());
    if(m.find())
        this.boundary = m.group(1);
    this.queryString = request.getQueryString();
  }

  /***
   * 用于得到指定字段的参数值,重写request.getParameter(String s)
   */
  public String getParameter(String key) {
    if (parameter.isEmpty()) {
      return null;
    }
    return (String) ((ArrayList)parameter.get(key)).get(0);
  }

  /***
   * 用于得到指定同名字段的参数数组,重写request.getParameterValues(String s)
   */
  public String[] getParameterValues(String key) {
    if (parameter.isEmpty()) return null;
    ArrayList al = parameter.get(key);
    return (String[])al.toArray(new String[al.size()]);
  }

  public String getQueryString() {
    return queryString;
  }

  public int getCount() {
    return count;
  }

  public String[] getFileName() {
    return fileName;
  }

  public void setMaxFileSize(long size) {
    maxFileSize = size;
  }

  public void setTagFileName(String filename) {
    tagFileName = filename;
  }


  /***
   * 设置上载文件要保存的路径
   */
  public void setSaveDir(String saveDir) {
    this.saveDir = saveDir;
    File testdir = new File(saveDir); //为了保证目录存在,如果没有则新建该目录
    if (!testdir.exists()) testdir.mkdirs();
  }

  /***
   * 设置字符集
   */
  public void setCharset(String charset) {
    this.charset = charset;
  }

  /***
   * 用户调用的上载方法
   */
  public boolean uploadFile() throws ServletException, IOException {
    setCharset(request.getCharacterEncoding());
    return uploadFile(request.getInputStream());
  }

  /***
   * 清理参数占用的数据结构资源.
   */
  public void clear(){
      Iterator i = this.parameter.values().iterator();
      while(i.hasNext()){
          ArrayList al = (ArrayList) i.next();
          al.clear();
      }
      parameter.clear();
  }

  /***
   * 取得InputStream中数据的主方法
   */
  private boolean uploadFile(ServletInputStream in) throws
      ServletException, IOException {
    String line = null;
    byte[] buffer = new byte[256];
    byte[] lastbuffer = null;
    int lastlen = 0;
    ArrayList<String> tmpFileName = new ArrayList();
    while ( (line = readLine(buffer, in, charset)) != null) {
      if (line.toLowerCase().startsWith("content-disposition: form-data;")) {

        if (line.indexOf("filename=") != -1) { //如果一段分界符内的描述中有filename=,说明是文件的编码内容
          String fName = getFileName(line);
          if (fName.trim().length() == 0) {
            continue;
          }
          if (count == 0 && tagFileName.length() != 0) {
              //对第一个文件扩展名进行特殊处理.
            String ext = fName.substring( (fName.lastIndexOf(".") + 1));
            fName = tagFileName + "." + ext;
          }
          tmpFileName.add(fName);
          
          count++;
          while ( (line = readLine(buffer, in, charset)) != null) {
            if (line.length() <= 2) {
              break;
            }
          }
          //System.out.println(fName);
          File f = new File(saveDir, fName);
          FileOutputStream out = new FileOutputStream(f);
          long size = 0l;
          lastbuffer = new byte[0];
          lastlen = 0;
          size += len;
          if (size >= maxFileSize) {
            throw new IOException("文件已超过最大值:" + this.maxFileSize + "字节");
          }
          while ( (line = readLine(buffer, in, null)) != null) {
            if (line.indexOf(boundary) != -1) {
              out.write(lastbuffer, 0, lastlen - 2);
              break;
            }
            out.write(lastbuffer, 0, lastlen);
            lastbuffer = arraycopy(buffer, 0, len);
            lastlen = len;
          }
          out.close();
        }
        else { //否则是字段编码的内容
          String key = getKey(line);
          StringBuilder value = new StringBuilder();
          while ( (line = readLine(buffer, in, charset)) != null) {
            if (line.length() <= 2) {
              break;
            }
          }
          while ( (line = readLine(buffer, in, charset)) != null) {
            if (line.indexOf(boundary) != -1) {
              break;
            }
            value.append(line);
          }
          put(key.trim(), value.toString().trim(), parameter);
        }
      }
    }

    if (queryString != null) {
      String[] each = split(queryString, "&");
      for (int k = 0; k < each.length; k++) {
        String[] nv = split(each[k], "=");
        if (nv.length == 2) {
          put(nv[0].trim(), nv[1].trim(), parameter);
        }
      }
    }
    fileName = tmpFileName.toArray(new String[tmpFileName.size()]);
    tmpFileName.clear();
    if (fileName.length == 0) {
      return false; //如果fileName数据为空说明没有上载任何文件
    }
    return true;
  }

  /***
   * 可以将多个value压入一上同名KEY中.
   */
  private void put(String key, String value, HashMap<String,ArrayList> hm) {
    ArrayList al = (hm.containsKey(key))?hm.get(key):new ArrayList();
    al.add(value);
    hm.put(key,al);
  }


  /***
   * 从输入流中读取一行数据到byte[]中同时返回该数据的String表示以例分析
   */
  private String readLine(byte[] lineBytes,ServletInputStream in, String charset) {
    try {
      len = in.readLine(lineBytes, 0, lineBytes.length);
      if (len == -1) return null;
      if (charset == null) return new String(lineBytes, 0, len);
      return new String(lineBytes, 0, len, charset);
    }
    catch (Exception ex) {
      return null;
    }
  }

  /***
   * 从描述字符串中分离出文件名
   */
  private String getFileName(String line) {
    Matcher m = Pattern.compile("filename=/"([^/"]*)/"").matcher(line);
    if(m.find()){
        String name =  m.group(1);
        int offset = name.lastIndexOf("//");
        name = name.substring(++offset);
        offset = name.lastIndexOf("/");
        name = name.substring(++offset);
        return name;
    }
    return "";
  }


  /***
   * 从描述字符串中分离出字段名
   */
  private String getKey(String line) {
    Matcher m = Pattern.compile("name//=/"([^/"]*)/"").matcher(line);
    if(m.find()) return m.group(1);
    return "";
  }

  /***
   * 不用正则表达式分割字符串
   */
  private static String[] split(String line, String mark) {
    if (line == null) return null;
    StringTokenizer st = new StringTokenizer(line, mark);
    ArrayList<String> tmp = new ArrayList();
    while (st.hasMoreTokens()) tmp.add(st.nextToken());
    String[] strArr = tmp.toArray(new String[tmp.size()]);
    tmp.clear();
    return strArr;
  }

  private static byte[] arraycopy(byte[] source, int offset, int len) {
      byte[] target = new byte[source.length];
      for (int i = offset; i < offset + len; i++) {
          target[i] = source[i];
      }
      return target;
  }
}

 

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值