【问题标题】:RichFaces fileupload and NullPointerExceptionRichFaces 文件上传和 NullPointerException
【发布时间】:2023-03-04 14:29:01
【问题描述】:

我正在尝试使用rich:fileUpload 将文件上传到服务器,代码如下:

@Name("fileUploader")
public class FileUploader {

private byte[] fileData;

    public void uploadFileListener(UploadEvent uploadEvent) {
        fileData = uploadEvent.getUploadItem().getData();
        //other code here
    }   
}

页面包含以下内容:

rich:fileUpload fileUploadListener="#{fileUploader.uploadFileListener}"

我得到的是 uploadEvent 包含有关文件名、大小等的数据...但是
uploadEvent.getUploadItem().getData();
返回 null...

我已经看到类似的问题here...但是没有答案...

谢谢!

【问题讨论】:

    标签: richfaces seam file-upload


    【解决方案1】:

    您是否在组件 xml 中配置了 multipart-filter?

    类似这样的:

    <web:multipart-filter create-temp-files="true" max-request-size="1000000" url-pattern="*.seam"/>
    

    更新:我不完全确定这是用于 s:fileUpload 还是 Rich:fileUpload。在考虑这个配置之前,请检查下面的代码。默认情况下,如果我没记错的话,您应该使用临时文件,这是我认为 RichFaces 的默认配置。抱歉,这里没有我的项目可供检查。

    如果您按照上面的方式进行配置,您的文件将被保存到一个临时文件 (create-temp-files="true"),在这种情况下,您应该使用以下方式访问您的数据

    uploadEvent.getUploadItem().getFile()
    

    您可以检查它是否存储在文件中:

    uploadEvent.getUploadItem().isTempFile()
    

    既然你说文件“元数据”在那里,这似乎是问题所在,你只是在错误的地方寻找你的数据:)

    如果您将其配置为 false,则您的方法应该可以工作。

    我还记得(不完全确定)上传控件(rich:upload)需要在 h:form 中

    希望对你有帮助。

    【讨论】:

    • 嘿!感谢您的回答,实际上我已将 添加到我的 components.xml ...而且你似乎是对的 h:form 总结一下:现在我正在使用 s:upload 上传文件,使用 h:commandButton ,但我需要的是使用 ajax 请求上传文件 - 使用 a4j:button (这不起作用 - 数据为空)...
    • 如果你想使用rich:Upload,你应该从你的组件xml中删除web:multipart-filter。要获取数据,您需要检查uploadEvent.getUploadItem().getFile() 而不是uploadEvent.getUploadItem().getData()。 getFile() 不适合你吗? “元数据”填满了吗?
    • 谢谢! uploadEvent.getUploadItem().getFile() 工作正常!
    【解决方案2】:

    让我们整理一下:

    首先,您必须定义是否要将数据直接上传到byte[] 缓冲区或临时文件以及支持的最大大小。这就是为什么你必须在某个地方定义两个参数的原因。

    现在您需要定义这些参数的位置取决于您使用的组件(即 seam fileUpload 组件或richfaces fileUpload 组件)以及为您的应用程序安装的技术。让我们看看:

    如果您使用带有richfaces 的seam 框架并且您不需要ajax 支持(即在上传完成后显示正在加载的图像),&lt;s:fileUpload&gt; 将是一个不错的选择,要配置它,您必须更改您的 seam components.xml 这样归档:

    <web:multipart-filter create-temp-files="true"
                          max-request-size="1000000" 
                          url-pattern="*.seam" />
    

    这意味着您发送到服务器的数据将保存在一个临时文件中,并且支持的最大大小为1000000(约1M)。更多信息可以在这里找到:http://seamframework.org/Documentation/HowToUploadAndDownloadFilesInSeam

    现在使用相同的技术堆栈(seam + richfaces),但在这种情况下,您需要使用 ajax 支持。在这种情况下,&lt;rich:fileUpload&gt; 将是您的选择。要配置它,只需在 web.xml 文件中定义的接缝过滤器中更改它:

    <filter>
        <filter-name>Seam Filter</filter-name>
        <filter-class>org.jboss.seam.servlet.SeamFilter</filter-class>
        <init-param>
            <param-name>createTempFiles</param-name>
            <param-value>false</param-value>
        </init-param>
        <init-param>
            <param-name>maxRequestSize</param-name>
            <param-value>10000000</param-value>
        </init-param>
    </filter>
    

    请注意,尽管两种情况下的参数相同,但它们是在不同的地方定义的——我想这在带有 CDDI 的 JEE6 中有所改变——。

    如果您的应用程序不使用 seam 框架但它确实使用了richfaces,您可能必须在web.xml 中再次在相应的richfaces 过滤器中定义此参数。

    现在是有趣的部分,&lt;rich:fileUpload&gt; 的用法。这是使用该组件的名为 BlockEdit.xhtml 的文件的相关部分:

           <rich:fileUpload
                fileUploadListener="#{blockHome.sketchListener}"
                maxFilesQuantity="1"
                reRender="table" 
                id="upload"
                immediateUpload="true"
                acceptedTypes="jpg, gif, png, bmp">
                    <a:support event="onuploadcomplete" reRender="sketchImage" />
           </rich:fileUpload>
    

    这是BlockHome.java的fileUploadListener

    public void sketchListener(UploadEvent event) {
        UploadItem item = event.getUploadItem();
        logger.info("Sketch listener executed ...");
        if(item != null && item.getData() != null) {
            logger.info(item.getFileName()+" "+item.getFileSize());
            getInstance().getSketch().setData(item.getData());
            getInstance().getSketch().setName(item.getFileName());
            getInstance().getSketch().setContentType(item.getContentType());
            getInstance().getSketch().setSize(item.getFileSize());
        }
    }
    

    如果您在 web.xml 的接缝过滤器内配置的createTempFiles 是:

        <init-param>
            <param-name>createTempFiles</param-name>
            <param-value>false</param-value>
        </init-param>
    

    那么 item.getData() 将不为空。但是,如果您将参数createTempFiles 定义为true,那么如果您想知道它是否有值,则应该询问 item.getFile()。这是因为 item.getData() 仅在您决定避免创建临时文件时才被填充,如 Richfaces demo fileUpload documentation 中所述。

    FileUpload 使用了两个应该在 Filter 中定义的初始化参数 web.xml 中的定义:

    createTempFiles布尔属性,它定义了是否 上传的文件存储在临时文件中或在侦听器中可用 就像 byte[] 数据(本例中为 false)。 maxRequestSize 属性定义最大大小(以字节为单位) 上传的文件(本例为 1000000)。

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-12
      • 2011-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-16
      • 2011-09-15
      • 1970-01-01
      相关资源
      最近更新 更多