资讯专栏INFORMATION COLUMN

Java Servlet实现文件上传

e10101 / 2522人阅读

摘要:翻了几篇教程,写出来了一个简单的文件上传接收代码。这里我们就真正建了一个的实例来处理文件的上传。可以设置上传文件的最大大小。参考的文章实现基本文件上传在中使用开源包实现文件上传功能

文件上传可以说是Web应用中很常用的一块,前几天打算研究一下HTML5提供的FileReader API,并且用Tomcat作为后端来实验大文件的上传(只是学校的课程作业必须用Java写,都不允许使用最好的编程语言php>.<)。可Java Servlet与php这种喜闻乐见的Web码农语言不同,并没有提供一个很简单的处理文件上传的API,所以还捣鼓了蛮久,也对一般的文件上传的HTML控件和实现原理稍微有了一点了解。

对面宿舍的一位同学说我很久没更了不太好,于是我就写一篇,谢谢他的提醒。

首先,我们都知道最常见的HTML的文件上传控件是喜闻乐见的,但一定要搭配form的属性enctype="multipart/form-data",服务器上要有一个接收上传的cgi或者别的什么,既然我们用java写,就叫uploadServlet。于是有了一个如下的常见的上传表单。

然后我们在后端处理。由于Java Servlet的API是没有提供什么$_FILES数组这样傻瓜式的文件操控方式,我们必须自己处理request。我们不妨先把收到的request输出到文件当中,看看Servlet会收到什么,再想想怎么处理。放这样一个servlet的代码:

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class UploadServlet extends HttpServlet{
    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        response.setContentType("text/plain;charset=utf-8");
        PrintWriter writer=response.getWriter();
        InputStream in=request.getInputStream();
        File f = new File("/tmp/upload");
        //把文件存到/tmp/upload
        FileOutputStream fout = new FileOutputStream(f);
        byte[] b=new byte[1024];
        int n=0;
        while ((n=in.read(b))!=-1){
            fout.write(b,0,n);
        }
        fout.close();
        in.close();
        writer.println("Finished uploading files!");
        writer.close();
    }
}

有了Servlet就拖出去跑一跑。这里我的表单不仅会发送文件,还会发送一个密码域。如果我随便发一个文本文件,那么我得到了这样的结果。

多上传几次还会发现那一堆横杠开头的数字会变动。这下不好玩了,虽然我们可以看到我们上传的数据,但要解析它有点过于复杂了。这个请求是依据RFC1867来写的,虽然有标准可依,但我们这么懒怎么会去依照标准写一个解析器呢?

于是我们需要请出Apache开发的文件上传处理库Commons FileUpload。这个网站提供了最新版的下载链接和基本的使用指南。文档讲得过于全面了,而我们一般不需要那么多功能,够用就好。翻了几篇教程,写出来了一个简单的文件上传接收代码。

javaimport javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
import org.apache.commons.fileupload.*;
import org.apache.commons.fileupload.servlet.*;
import org.apache.commons.fileupload.disk.*;

首先需要多装载三个库,以及一个java.util.List,因为到时候处理的时候,Commons FileUpload会把搞成一个List返回回来,我们需要接收这个List并处理解析它。

public class UploadServlet extends HttpServlet{
    private String filepath;
    private String temppath;
    private String buf;
    public void init(ServletConfig config) throws ServletException{
        super.init(config);
        ServletContext context=getServletContext();
        filepath=context.getRealPath("/"+config.getInitParameter("filepath"));
        temppath=context.getRealPath("/"+config.getInitParameter("temppath"));
    }

为了方便维护,我把保存上传文件的目录用Init Parameter的方式写到web.xml里面去,然后在这个地方读出来。我们需要一个保存上传文件的目录和一个用来做缓存的临时目录。如果你接收上传文件之后不打算保存而是直接拿去处理,也没有问题,但是一定要有一个缓存目录,在后面有用。

接下来是真正激动人心的处理上传的代码了。我懒得写doGet了所以就只有一个doPost。

     @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        response.setContentType("text/plain;charset=utf-8");
        PrintWriter writer=response.getWriter();
        int count=0;
        try{
            DiskFileItemFactory diskFactory = new DiskFileItemFactory();
            diskFactory.setSizeThreshold(4 *1024 );
            diskFactory.setRepository(new File(temppath));

这里我们开了一个diskFactory,就是FileUpload所需要使用的缓存,当内存存不下上传的文件的时候,它会自动写入缓存目录。通过setSizeThreshold方法可以设置内存的使用上限,也就是当内存用了这么多却还存不下,就开始写缓存。显然这个值很大程度上会决定这个Servlet的效率。

    ServletFileUpload upload = new ServletFileUpload(diskFactory);
    upload.setSizeMax(4 * 1024 * 1024);
    List fileItems = upload.parseRequest(request);
    Iterator iter = fileItems.iterator();

这里我们就真正建了一个ServletFileUpload的实例upload来处理文件的上传。可以设置上传文件的最大大小。然后把request对象直接交给upload来解析,它会返回一个一个List,这个List的每一项实际上是一个FileItem对象,后面就要用迭代器处理这个列表。

    while (iter.hasNext()){
        FileItem item = (FileItem) iter.next();
        if (item.isFormField()){
            writer.println(item.getFieldName()+" : "+item.getString());
        }

要注意的是ServletFileUpload也会处理非文件的信息,可以用isFormField方法来检查,然后将信息获取出来。但这在这里不是重点,只是必须要处理掉而已。

        else{
            String filename = item.getName();
            filename = filename.substring(
            filename.lastIndexOf("")+1,filename.length());
            File uploadFile = new File(filepath+"/"+filename);
            item.write(uploadFile);
            writer.println("Get file:"+ filename);
            writer.println(" filetype: "+item.getContentType());
            count++;
        }
        }
    } catch (Exception e){
        e.printStackTrace();
    }
    writer.println("Finished uploading files!");
    writer.close();
}
}

处理文件的代码就这么点,如果还要说什么的话,就是每个文件的FileItem对象不仅可以用write方法来直接写到什么文件里面去,也可以用getInputStream方法得到一个输入流来解析,或者用get方法直接读到一个byte数组里面去。可以说这个库提供了一个很方便的方法解析上传的文件。

最后提一下,Apache Commons是一个Java增强库,提供了大量的优质Java资源库,涉及很多开发领域。如果不出意外,应该我会在近期写一篇关于JavaScript FileReader的blog,敬请期待。

参考的文章:
Servlet实现基本文件上传
在Servlet中使用开源fileupload包实现文件上传功能

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/35743.html

相关文章

  • java Web开发实现手机拍照上传到服务器

    摘要:第一步搭环境基本我们要清楚自己的版本。因为我们配置的成功的前提是版本相对应。解压缩都随便一个盘都行,下图是我的路径配置相关环境变量,由于本人之前已经配置了开发时环境,即。这个显示上传状态与后面在中有定义。 第一步: 搭环境,基本jdk 1.6+apache tomcat6.0+myeclipse2014 1.我们要清楚自己的jdk版本。因为我们Apache Tomcat配置的成...

    only_do 评论0 收藏0
  • java Web开发实现手机拍照上传到服务器

    摘要:第一步搭环境基本我们要清楚自己的版本。因为我们配置的成功的前提是版本相对应。解压缩都随便一个盘都行,下图是我的路径配置相关环境变量,由于本人之前已经配置了开发时环境,即。这个显示上传状态与后面在中有定义。 第一步: 搭环境,基本jdk 1.6+apache tomcat6.0+myeclipse2014 1.我们要清楚自己的jdk版本。因为我们Apache Tomcat配置的成...

    Towers 评论0 收藏0
  • 使用Spring实现上传文件

    摘要:要使用容器上传文件,您需要注册一个类在中。最好不要使用内容加载应用程序的文件系统。允许用户上传文件的表单从后端提供的文件列表调整文件上传限制配置文件上传时,设置文件大小限制通常很有用。 本指南将指导您完成创建可以接收HTTP多文件上传服务器应用程序的过程。 你要构建什么 您将创建一个接受文件上传的Spring Boot Web应用程序。您还将构建一个简单的HTML界面来上传测试文件。 ...

    yuanzhanghu 评论0 收藏0
  • 使用WebUploader实现图片上传

    摘要:前言案例使用的开发工具不足之处希望各位大佬们多多指教顶包文件代码图片路径选择图片代码图片上传选完文件后,是否自动上传。内部根据当前运行是创建,可能是元素,也可能是这里是的文件上传方式,或者。默认值设置文件上传域的。 前言:         案例使用的开发工具:eclipse         ...

    nifhlheimr 评论0 收藏0
  • servlet上传下载

    摘要:一添加项目依赖二上传上传文件存储目录上传配置上传文件最大值检测是否为多媒体上传如果不是则停止表单必须包含配置上传参数设置最大文件上传值中文处理构造临时路径来存储上传的文件这个路径相对当前应用的目录如果目录不存在则创建解析请求的内容 一、添加项目依赖(gradle) dependencies { compile group: javax.servlet, name: javax....

    xuweijian 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<