【问题标题】:Understand Working File Upload Solution了解工作文件上传解决方案
【发布时间】:2012-12-06 15:28:23
【问题描述】:

我已经编写了下面的方法,该方法由我的 doPost 方法调用来解析请求中给出的multipart/form-data。这一切都很好,我只是不明白发生了什么。如果有人能在我的尝试中分解这三行,我将不胜感激。我已经通读了Apache Commons File Upload documentation,但这对我来说没有意义,我讨厌编写我不完全理解的代码。特别是,我想知道创建工厂和上传对象时实际发生了什么。

public static List<FileItem> parseFormRequest(HttpServletRequest request)
{
    List<FileItem> items = null;

    try 
    {
        DiskFileItemFactory factory = new DiskFileItemFactory();
        ServletFileUpload upload = new ServletFileUpload(factory);
        items = upload.parseRequest(request);
    } 
    catch (FileUploadException error) 
    {
        System.out.println("UploadFileServlet - Error With File Parsing - " + error.getMessage());
    }

    return items;
}

额外帮助!

我还在upload.parseRequest(request) 下收到一条警告,上面写着Type safety: The expression of type List needs unchecked conversion to conform to List&lt;FileItem&gt;。如果有人也可以解释这一点,那真的会帮助我完成我所做的事情。谢谢

【问题讨论】:

    标签: java jsp servlets file-upload


    【解决方案1】:

    工厂只是一个帮手,我稍后会解释。主要工作由ServletFileUpload完成。

    ServletFileUpload 将扫描所有上传的文件(使用解析 MIME 内容并知道如何处理边界标记、内容长度等的迭代器)。

    对于每个上传的文件,parse 方法要求 FileItemFactory 为上传的文件创建一个本地表示,然后将内容从内存(例如,来自内存中的 HTTP POST 请求)复制到实际文件在磁盘上。

    简化,流程如下:

    • 获取下一个上传的文件
    • 向工厂索要本地文件(“FileItem”)
    • 将内存中的内容(来自 HttpServletRequest)复制到本地文件(如果是 DiskFileItemFactory,则为 java.io.File)
    • 循环直到 HTTP 请求结束

    详见以下类的源码

    • org.apache.commons.fileupload.FileUploadBase.parseRequest(RequestContext)
    • org.apache.commons.fileupload.FileUploadBase.FileItemIteratorImpl.FileItemStreamImpl

    这种设计允许切换到另一个文件存储设施,例如: 您可以将 DiskFileItemFactory 替换为您自己的 DatabaseFileItemFactory,因此上传的文件将存储在数据库中,而不是服务器上的本地文件中。代码更改只会影响一行,其余的 commons-fileupload 可以按原样使用(例如,解析 HTTP 请求,迭代上传 文件等)

    对于第二个问题:commons-fileupload 好像兼容Java 1.4,所以返回类型为parseRequest() 实际上是一个未键入的java.util.List - 它缺少列表仅包含 FileItem 对象的声明(例如java.util.List&lt;FileItem&gt;)。 由于您将变量 items 声明为 List&lt;FileItem&gt; 类型,Java 编译器会警告您这种不匹配。

    在这种情况下,您的操作是正确的,您可以通过添加以下内容来忽略警告:

    @SuppressWarnings( "unchecked" )
    public static List<FileItem> parseFormRequest(HttpServletRequest request)
    {
       ...
    

    【讨论】:

    • +1 因为我快写完一个非常相似的回复,但你的措辞更好。 DatabaseFileItemFactory 理念适用于未来请求可能需要访问上传数据的集群环境。如果临时本地文件仅在接收原始请求的节点上可用,则数据库条目的密钥可以存储在会话中并廉价地复制到其他节点以便更好地进行故障转移处理。
    • 我对 DiskFileItemFactory 感到困惑。这是如何写入文件的,以及由于我没有明确位置,它写入到哪里。它只是写入文件然后立即删除吗?
    • "DiskFileItemFactory 将它们的内容保存在内存中,用于较小的项目,或者保存在磁盘上的临时文件中,用于较大的项目。大小阈值,超过该阈值的内容将存储在磁盘上,是可配置的,如是将在其中创建临时文件的目录。”。您需要使用 FileItem.write(yourFile) 将上传的文件保存到未自动清理的位置。
    【解决方案2】:

    你需要花一些时间在documentation

    据我所知,ServletFileUpload 实例使用您提供的工厂来实际创建请求中的文件实例。您使用了将文件写入磁盘的工厂;不过还有其他选择(例如内存)。通过指定工厂,您可以指定所创建文件的类型。

    当你打电话时

    upload.parseRequest(request)

    ServletFileUpload 实例通过请求数据并实际使用工厂创建它找到的文件,并将它们以列表的形式返回给您。

    如果您查看parseRequest documentation,您会注意到该方法仅返回List。在您的代码中,您将该返回的列表分配给List&lt;FileItem&gt;。这需要强制转换,这就是您收到编译器警告的原因。

    【讨论】:

    • 我不明白为什么我将一个列表分配给一个列表时会收到警告
    • 您将List&lt;FileItem&gt; 分配给列表
    • 所以我需要做一个 (List) 演员表
    • 你没有;它正在为你做。
    • 那么我可以写些什么来消除警告吗?
    【解决方案3】:

    我需要用于调用此函数的 java 代码... 我需要用于向 HttpServletRequest 添加参数的 Servlet 代码

    【讨论】:

      猜你喜欢
      • 2021-01-14
      • 1970-01-01
      • 1970-01-01
      • 2011-09-27
      • 2013-10-25
      • 2012-11-08
      • 2014-02-02
      • 2012-10-14
      • 1970-01-01
      相关资源
      最近更新 更多