首页 > 其他分享 >commons.FileUpload的使用

commons.FileUpload的使用

时间:2023-06-15 11:32:09浏览次数:35  
标签:FileUpload request upload commons item file 使用 data



Using FileUpload

使用FileUpload

FileUpload can be used in a number of different ways, depending upon the requirements of your application. In the simplest case, you will call a single method to parse the servlet request, and then process the list of items as they apply to your application. At the other end of the scale, you might decide to customize FileUpload to take full control of the way in which individual items are stored; for example, you might decide to stream the content into a database.

FileUpload可以根据应用程序的需求在很多不同的地方使用。举个很简单的例子,你可能调用一个简单的方法去编译servlet请求,并且把这些项目作为你的应用程序一部分来应用。从另一个方面来讲,你可能想自定义FileUpload来完成所有项目的存储;再来个例子,你可能想流化内容而存入数据库。

Here, we will describe the basic principles of FileUpload, and illustrate some of the simpler - and most common - usage patterns. Customization of FileUpload is described elsewhere .

这里我们会介绍FileUpload基础的使用原则,并描述一些简单的通用的使用模式。关于FileUpload自定义的介绍会在其它地方(其实那里什么也没有)讲。

How it works

简介

A file upload request comprises an ordered list of items that are encoded according to RFC 1867 , "Form-based File Upload in HTML". FileUpload can parse such a request and provide your application with a list of the individual uploaded items. Each such item implements t he FileItem interface, regardless of its underlying implementation.

一个上传请求由一系列根据RFC1867(这个文章我已经放在BLOG收藏夹HTML目录下)编码的项目。FileUpload可以编译这样的请求并将这一系列的个性化上传项目传递给你的应用程序。每一个这样的项目都实现了FielItem接口,不管它是怎么实现的。

Each file item has a number of properties that might be of interest for your application. For example, every item has a name and a content type, and can provide an InputStream to access its data. On the other hand, you may need to process items differently, depending upon whether the item is a regular form field - that is, the data came from an ordinary text box or similar HTML field - or an uploaded file. The FileItem interface provides the methods to make such a determination, and to access the data in the most appropriate manner.

每一个文件项目有一些自己的属性,这些属性也许正是你的应用程序感兴趣的地方。例如,每个项目有个一个名字和内容类型,并且可以提供一个输入流来访问这写数据。另一方面来看,你可能需要用不同方式来处理不同的项目,这就依赖与项目是否是一个正常的字域,也就是说,这些数据来自于一个普通的文本框或类似HTML的字域或一个上传文件。FileItem接口提供一些方法来做这样一个决定,并且访问这些数据用最合适的方法。

FileUpload creates new file items using a FileItemFactory . This is what gives FileUpload most of its flexibility. The factory has ultimate control over how each item is created. The default factory stores the item's data in memory or on disk, depending on the size of the item (i.e. bytes of data). However, this behavior can be customized to suit your application.

FileUpload使用FileItemFactory创建一个新的文件项目。对于FileUpload来说这是完全可行的。工厂是唯一全盘控制每个项目的创建的工具。默认的工厂存储项目的数据在内存或者硬盘里,这都依赖于项目的大小(如,数据字节数组)。不过,还是可以把它定义成为合适你的应用程序使用的。

Parsing the request

Before you can work with the uploaded items, of course, you need to parse the request itself. Ensuring that the request is actually a file upload request is straightforward, but FileUpload makes it simplicity itself, by providing a static method to do just that.

在使用上传项目工作之前,你还需要编译请求。最重要的事情就要确定这个请求确实来自于文件上传,不过FileUpload利用一个静态方法使它自身简单化了。

// Check that we have a file upload request 
boolean isMultipart = FileUpload.isMultipartContent(request); 
Now we are ready to parse the request into its constituent items.

现在我们可以准备开始编译请求了。

The simplest case

简单的例子

The simplest usage scenario is the following: 
>>Uploaded items should be retained in memory as long as they are reasonably small. 
>>Larger items should be written to a temporary file on disk. 
>>Very large upload requests should not be permitted. 
>>The built-in defaults for the maximum size of an item to be retained in memory, the maximum permitted size of an upload request, and the location of temporary files are acceptable.

下面是一些简单的使用场景:

>>上传项目只要足够小,就应该保留在内存里。

>>较大的项目应该被写在硬盘的临时文件上。

>>非常大的上传请求应该避免。

>>限制项目在内存中所占的空间,限制最大的上传请求,并且设定临时文件的位置。

Handling a request in this scenario couldn't be much simpler:

处理这个场景的请求很简单:

// Create a new file upload handler 
DiskFileUpload upload = new DiskFileUpload();
// Parse the request List 
/* FileItem */ items = upload.parseRequest(request); 
That's all that's needed. Really!

这就是我们所需要的全部代码了!

The result of the parse is a List of file items, each of which implements the FileItem interface. Processing these items is discussed below.

编译的结果就是生成了一系列文件项目,每个文件项目实现一个FileItem接口。下面将介绍如何处理这写项目。

Exercising more control

控制练习

If your usage scenario is close to the simplest case, described above, but you need a little more control over the size thresholds or the location of temporary files, you can customize the behavior using the methods of the DiskFileUpload class, like this:

如果你的使用场景和最简单例子很接近,但是你又需要一点点扩展的控制,包括大小的极限或者临时文件的设置等,你可以通过DiskFileUpload类的方法来自定义行为,像这样:

// Create a new file upload handler 
DiskFileUpload upload = new DiskFileUpload(); 
// Set upload parameters 
upload.setSizeThreshold(yourMaxMemorySize); 
upload.setSizeMax(yourMaxRequestSize); 
upload.setRepositoryPath(yourTempDirectory); 
// Parse the request List 
/* FileItem */ items = upload.parseRequest(request); 
Of course, each of the configuration methods is independent of the others, but if you want to configure them all at once, you can do that with an alternate parseRequest() method, like this:

当然,每个配置方法是独立于其它任意一个的,但是如果你想一次性配置他们,你可以用parseRequest()的另一个重载方法,像这样:

// Create a new file upload handler 
DiskFileUpload upload = new DiskFileUpload(); 
// Parse the request List 
/* FileItem */ items = upload.parseRequest(request, yourMaxMemorySize, yourMaxRequestSize, yourTempDirectory); 
Should you need further control over the parsing of the request, such as storing the items elsewhere - for example, in a database - you will need to look into customizing FileUpload.

如果你还想使用更多的控制,比如存储项目到其它地方(如,数据库),那么你可以看FileUpload自定义(这个连接又是个假的,空页面)介绍。

Processing the uploaded items

处理上传项目

Once the parse has completed, you will have a List of file items that you need to process. In most cases, you will want to handle file uploads differently from regular form fields, so you might process the list like this:

一旦编译完成,那么你会得到一个待处理的文件项目列表。很多的情况下,你会想单独处理每个特定的项目,因此,你可以这样做:

// Process the uploaded items 
Iterator iter = items.iterator(); 
while (iter.hasNext()) 
{ 
    FileItem item = (FileItem) iter.next();
    if (item.isFormField()) 
    { 
       processFormField(item); 
    } 
    else
     { 
       processUploadedFile(item); 
    } 
}

For a regular form field, you will most likely be interested only in the name of the item, and its String value. As you might expect, accessing these is very simple.

对于普通的表单字域来说,你可能对项目的名称很感兴趣。完成你的需求真的很简单,照下面的做:

// Process a regular form field 
if (item.isFormField())
{ 
    String name = item.getFieldName(); 
    String value = item.getString(); ... 
}

For a file upload, there are several different things you might want to know before you process the content. Here is an example of some of the methods you might be interested in.

对于上传文件,这里就有很多不同啦~你可能想知道更多其它的内容。下面是个例子,里面包含了不少有趣的方法。

// Process a file upload
if (!item.isFormField()) 
{ 
    String fieldName = item.getFieldName(); 
    String fileName = item.getName(); 
    String contentType = item.getContentType(); 
    boolean isInMemory = item.isInMemory(); 
    long sizeInBytes = item.getSize();
     ... 
}

With uploaded files, you generally will not want to access them via memory, unless they are small, or unless you have no other alternative. Rather, you will want to process the content as a stream, or write the entire file to its ultimate location. FileUpload provides simple means of accomplishing both of these.

对于上传的文件,你肯定不希望总是通过内存来访问它,除非它很小,或者你实在没有别的选择余地了。你很希望使用流来处理文件内容或者写文件实体到它最终的地址。FileUpload提供简单的方式,来完成两方面的需求。

// Process a file upload
if (writeToFile) 
{
     File uploadedFile = new File(...); 
    item.write(uploadedFile); 
} 
else 
{ 
    InputStream uploadedStream = item.getInputStream(); 
    ... 
    uploadedStream.close(); 
}

Note that, in the default implementation of FileUpload, write() will attempt to rename the file to the specified destination, if the data is already in a temporary file. Actually copying the data is only done if the rename fails, for some reason, or if the data was in memory. If you do need to access the uploaded data in memory, you need simply call the get() method to obtain the data as an array of bytes.

注意:在 FileUpload的默认实现中wirte()方法应该值得关注,如果数据还在临时文件没有移除,那么这个方法就会试图重命名这个文件为相应的目标文件。事实上如果重命名失败了的话,数据就仅仅被拷贝。如果你需要访问内存中的上传数据,你可以用get()方法来获得数据的二进制数组形式。

// Process a file upload in memory

byte[] data = item.get(); ...

What's next

下一步做什么

Hopefully this page has provided you with a good idea of how to use FileUpload in your own applications. For more detail on the methods introduced here, as well as other available methods, you should refer to the JavaDocs .

希望这个文章对你使用FileUpload有一些帮助。对于更多的细节,还是要阅读配套的文档。

The usage described here should satisfy a large majority of file upload needs. However, should you have more complex requirements, FileUpload should still be able to help you, with it's flexible customization capabilities.

这个使用简介应该是足够满足你大部分的需求。但是如果你有更复杂的需求的话,你还要自定义合适的可行方案。

使用举例

1. 在一个 html 网页中,写一个如下的form :




用户可以选择多个文件,填写表单其它项,点击“提交”按钮后就开始上传给 http://127.0.0.1/upload_file/UploadFile 这是一个 servelet 程序

注意 enctype="multipart/form-data", method=post, type="file" 。根据 rfc1867, 这三个属性是必须的。multipart/form-data 是新增的编码类型,以提高二进制文件的传输效率。具体的解释请参阅 rfc1867






用户可以选择多个文件,填写表单其它项,点击“提交”按钮后就开始上传给 http://127.0.0.1/upload_file/UploadFile 这是一个 servelet 程序

注意 enctype="multipart/form-data", method=post, type="file" 。根据 rfc1867, 这三个属性是必须的。multipart/form-data 是新增的编码类型,以提高二进制文件的传输效率。具体的解释请参阅 rfc1867






用户可以选择多个文件,填写表单其它项,点击“提交”按钮后就开始上传给 http://127.0.0.1/upload_file/UploadFile 这是一个 servelet 程序

注意 enctype="multipart/form-data", method=post, type="file" 。根据 rfc1867, 这三个属性是必须的。multipart/form-data 是新增的编码类型,以提高二进制文件的传输效率。具体的解释请参阅 rfc1867






用户可以选择多个文件,填写表单其它项,点击“提交”按钮后就开始上传给 http://127.0.0.1/upload_file/UploadFile 这是一个 servelet 程序

注意 enctype="multipart/form-data", method=post, type="file" 。根据 rfc1867, 这三个属性是必须的。multipart/form-data 是新增的编码类型,以提高二进制文件的传输效率。具体的解释请参阅 rfc1867

<form enctype="multipart/form-data" action="http://127.0.0.1/UploadFile" method=post> 



    load multi files :<br> 



    <input name="userfile1" type="file"><br> 



    <input name="userfile2" type="file"><br> 



    <input name="userfile3" type="file"><br> 



    <input name="userfile4" type="file"><br> 



    text field :<input type="text" name="text" value="text"><br> 



    <input type="submit" value="提交"><input type=reset> 



</form>


用户可以选择多个文件,填写表单其它项,点击“提交”按钮后就开始上传给 http://127.0.0.1/upload_file/UploadFile 这是一个 servelet 程序

注意 enctype="multipart/form-data", method=post, type="file" 。根据 rfc1867, 这三个属性是必须的。multipart/form-data 是新增的编码类型,以提高二进制文件的传输效率。具体的解释请参阅 rfc1867

2. 服务端 servelet 的编写

现在第三方的 http upload file 工具库很多。Jarkata 项目本身就提供了fileupload 包http://jakarta.apache.org/commons/fileupload/ 。文件上传、表单项处理、效率问题基本上都考虑到了。在 struts 中就使用了这个包,不过是用 struts 的方式另行封装了一次。这里我们直接使用 fileupload 包。至于struts 中的用法,请参阅 struts 相关文档。

这个处理文件上传的 servelet 主要代码如下:

public void doPost( HttpServletRequest request, HttpServletResponse response ) { 



    DiskFileUpload diskFileUpload = new DiskFileUpload(); 



    // 允许文件最大长度 



    diskFileUpload.setSizeMax( 100*1024*1024 ); 



    // 设置内存缓冲大小 



    diskFileUpload.setSizeThreshold( 4096 ); 



    // 设置临时目录 



    diskFileUpload.setRepositoryPath( "c:/tmp" ); 







    List fileItems = diskFileUpload.parseRequest( request ); 



    Iterator iter = fileItems.iterator(); 



    for( ; iter.hasNext(); ) { 



        FileItem fileItem = (FileItem) iter.next(); 



        if( fileItem.isFormField() ) { 



            // 当前是一个表单项 



            out.println( "form field : " + fileItem.getFieldName() + ", " + fileItem.getString() ); 



        } else { 



            // 当前是一个上传的文件 



            String fileName = fileItem.getName(); 



            fileItem.write( new File("c:/uploads/"+fileName) ); 



        } 



    } 



}

标签:FileUpload,request,upload,commons,item,file,使用,data
From: https://blog.51cto.com/u_16065168/6485843

相关文章

  • diamond_使用与简介
     它是什么diamond为应用系统提供了获取配置的服务,应用不仅可以在启动时从diamond获取相关的配置,而且可以在运行中对配置数据的变化进行感知并获取变化后的配置数据.为什么需要它diamond的特点是简单、可靠、易用:简单:整体结构非常简单,从而减少了出错的可能性。可靠:应用方在任何情况......
  • 如何使用libavcodec将.yuv图像序列编码为.h264的视频码流?
    1.实现打开和关闭输入文件和输出文件的操作点击查看代码//io_data.cppstaticFILE*input_file=nullptr;staticFILE*output_file=nullptr;int32_topen_input_output_files(constchar*input_name,constchar*output_name){if(strlen(input_name)==0||strlen(ou......
  • elasticsearch的使用
    elasticsearch的使用索引管理1、创建索引对比关系型数据库,创建索引相当于创建数据库url:http:/ip:9200/test方式:PUT不允许重复put相同索引2、获取索引a、将请求方式改为get即获取当前索引信息url:ip:9200/test方式:GETb、获取所有索引信息url:ip:9200/_ca......
  • 如何生成和使用requirements.txt
    当开发Python项目时,使用第三方库是很常见的。为了确保项目的可移植性和可重复性,通常会将项目所依赖的库及其版本记录在一个名为requirements.txt的文件中。这样,其他人可以通过该文件轻松地安装项目所需的所有库及其指定版本。以下是如何使用pip生成和安装requirements.txt......
  • 使用Spring Boot和H2完全工作的原型
    我们在Spring中使用了很多H2,特别是用于单元测试。但是,我们可能希望拥有一个包含数据的全功能原型,而不是单元测试。H2是完美的候选者。它适用于Spring,与大多数数据库具有很强的语法兼容性,并提供用于检查数据的UI。想象一下面试任务的情景。您希望您的示例开箱即用,尽可能少的配置为审......
  • 为什么软件要使用代码签名证书?
    在当下木马和病毒横行的互联网世界,越来越多的软件被恶意攻击,这一现实状况使得用户开始在下载软件之前验证其真实性。而代码签名证书的作用正在于验证软件的真实来源,它将向用户证明负责该代码的企业或个人的身份,并确认该代码自应用签名以来从未修改过。代码签名的定义代码签名是......
  • docker安装与使用教程
    https://mp.weixin.qq.com/s?__biz=MjM5NTY1MjY0MQ==&mid=2650860524&idx=3&sn=02dfc31d637f70b066a6ef9842beeac5&chksm=bd017ea28a76f7b466773e68f7dab26e65ffae2918c28aa1d87c84acfc54460a7b82aa57279f&scene=27  官方的一键安装方式:curl -fsSL https://ge......
  • C#中使用CAS实现无锁算法
    CAS的基本概念CAS(Compare-and-Swap)是一种多线程并发编程中常用的原子操作,用于实现多线程间的同步和互斥访问。它操作通常包含三个参数:一个内存地址(通常是一个共享变量的地址)、期望的旧值和新值。CompareAndSwap(内存地址,期望的旧值,新值)CAS操作会比较内存地址处的值与期望......
  • 使用cordova
    常用指令提前搭建好node环境使用node安装cordovanpminstall-gcordova创建项目cordovacreateHelloCordovaio.hellocordovaCordovaApp添加插件cordovapluginaddeg:cordovapluginaddcordova-plugin-file添加平台cordovaplatformadd查看平台和插件下的......
  • 使用sessionStorage获取值和设置值 sessionStorage.setItem('key','value') sessionS
    使用sessionStorage获取值和设置值sessionStorage.setItem('key','value')sessionStorage.getItem('myname')https://www.shuzhiduo.com/A/lk5a4ZL2J1/<body><buttonid="btn1">设置值</button><buttonid="btn2&......