【问题标题】:enctype="multipart/form-data" does not submit data with Seam multipart-filterenctype="multipart/form-data" 不使用 Seam multipart-filter 提交数据
【发布时间】:2016-04-02 08:08:27
【问题描述】:

自从我将以下配置添加到 components.xml 以自定义编辑器插件后,我的应用程序中每个带有 enctype="multipart/form-data" 的表单都不会提交数据。 我找不到任何消息来源说这是冲突的。

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

我正在使用 Seam 2.2.2 和 Jsf 1.2

更新:我想我可以停止使用 enctype="multipart/form-data" 的表单。但我不能。我需要一些帮助,还有更多信息。

首先:上述问题仅适用于 a4j 表单和 a4j 命令按钮。 正如我之前所说,我在 components.xml 中添加了上面的 web:multipart-filter 配置以使这个编辑器插件工作(这是通过 apache commons ServletFileUpload 完成的)。 我正在从项目表单中删除 enctype 配置以使一切正常,但有一种情况是不可能的。当我必须上传图片时。但是当我使用 url-pattern="*.seam":

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

然后上传工作,但 ServletFileUpload 没有。 如果我不使用任何 web:multipart-filter 这也会发生。 (图片上传成功,插件失败)

现在是这样的:

<h:form id="editPhoto" enctype="multipart/form-data">   

        <div id="photoAttribute" class="attribute-relationship spacer-top-bottom">
            <div class="label">
                <h:outputText>#{messages['person.photo.alter']} </h:outputText>
            </div>
            <s:fileUpload id="photoPerson" 
                    data="#{person.profilePhoto}" 
                    fileName="#{person.profilePhotoName}" 
                    fileSize="#{person.profilePhotoSize}"
                    accept="images/*">
            </s:fileUpload>
        </div>

        <h:commandButton id="editPersonButtonTop" 
            value="#{messages['button.savePhoto']}" 
            action="#{personController.prepareSavePhoto(person)}" 
            styleClass="button btn-info"  
            onclick="showAjaxStatus()"/>
</h:form>

似乎我在这里缺少一些 ajax 配置,但我不知道它是什么。还有为什么我不能同时上传 ServletFileUpload 和图片?

ServletFileUpload 来自 commons-fileupload-1.3.1,它的工作方式如下:

List<FileItem> items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);
processItems(items);
saveOpenAttachment();
...

private void processItems(List<FileItem> items)
{
    // Process the uploaded items
    Iterator<FileItem> iter = items.iterator();
    while (iter.hasNext()) {
        FileItem item = iter.next();

        if (!item.isFormField()) 
        {
            processUploadedFile(item);
        }
    }

}

private void processUploadedFile(FileItem item)
{
    setFileName(FilenameUtils.getName(item.getName()));
    try
    {
        InputStream fileContent = item.getInputStream();
        byte[] bytes = IOUtils.toByteArray(fileContent);
        setFileData(bytes);
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
    setFileContentType(item.getContentType());
}

如果有人能告诉我如何设法使 ServletFileUpload 与以前的组件配置一起工作,或者如何让表单提交数据,我将不胜感激。

我的 components.xml:

<core:init debug="true" jndi-pattern="@jndiPattern@"/>

<web:rewrite-filter view-mapping="*.seam"/> 

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

<core:manager concurrent-request-timeout="10000" 
             conversation-timeout="3720000" 
             conversation-id-parameter="cid"
             parent-conversation-id-parameter="pid"
             default-flush-mode="MANUAL"/>

<persistence:managed-persistence-context name="entityManager"
                                 auto-create="true"
                  persistence-unit-jndi-name="java:/SinapseEntityManagerFactory"/>                          

<security:identity authenticate-method="#{authenticatorContext.authenticate}" remember-me="true" />

<international:time-zone-selector time-zone-id="GMT-3"/>
<international:locale-selector name="defaultLocale" locale-string="pt" scope="application" />
<international:locale-selector locale-string="pt" />

<event type="org.jboss.seam.security.notLoggedIn">
    <action execute="#{redirect.captureCurrentView}"/>
</event>
<event type="org.jboss.seam.security.postAuthenticate">
    <action execute="#{redirect.returnToCapturedView}"/>
</event>

<async:quartz-dispatcher/>  

<cache:jboss-cache-provider configuration="ehcache.xml" />
<transaction:ejb-transaction/>

【问题讨论】:

    标签: jsf file-upload seam jsf-1.2 seam2


    【解决方案1】:

    只是一个幸运的猜测,通过添加

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

    Seam 注册了一个 Multipart Filter 并将所有请求包装为 Seam MultipartRequest,我认为 commons-fileupload 无法处理它。

    有关更多信息,您可以访问 org.jboss.seam.web.MultipartFilter.java 第 78 行

    【讨论】:

    • 你是对的。我调试了 MultipartFilter,似乎当我使用与“* .seam”不同的任何 url 模式时,它不会调用此过滤器。
    【解决方案2】:

    为了解决我的问题,我更改了 apache-commons FileUpload 解决方案来处理请求,就像 Seam 多部分过滤器所做的那样:

    ServletRequest request = (ServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
    try
    {
      if (!(request instanceof MultipartRequest))
      {
         request = unwrapMultipartRequest(request);
      }
    
      if (request instanceof MultipartRequest)
      {
         MultipartRequest multipartRequest = (MultipartRequest) request;
    
         String clientId = "upload";
         setFileData(multipartRequest.getFileBytes(clientId));
         setFileContentType(multipartRequest.getFileContentType(clientId));
         setFileName(multipartRequest.getFileName(clientId));
         saveOpenAttachment();
      }
    }
    

    这样,我可以取消破坏其他请求的 web:multipart-filter 配置。

    【讨论】:

      猜你喜欢
      • 2011-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-28
      相关资源
      最近更新 更多