ICEfaces/Seam 文件上传组件不上传文件
Posted
技术标签:
【中文标题】ICEfaces/Seam 文件上传组件不上传文件【英文标题】:ICEfaces/Seam file upload component not uploading files 【发布时间】:2012-10-12 02:46:57 【问题描述】:更新
我目前正在 ICEfaces 论坛上解决我的问题 - 遗憾的是,提供的选项现在都没有导致解决方案,但它们确实让我对整个 JSF 主题有了更多的了解(感谢 BalusC那,通常:-))。
如果问题最终得到解决,我会尽量保持这个帖子的最新状态并发布答案,以帮助可能遇到它的其他人。
到目前为止,我的发现是:
需要禁用 Seam Multipart Filter,因为它会阻止 fileEntry-component 正常工作 我的应用程序中仍然存在一些令人讨厌的库问题,导致(静默)类加载问题:存在 2 个 icefaces-ace.jar 文件,一个在 EAR/lib 中,一个在 EAR/WAR/WEB-INF/lib .从 WEB-INF 中删除一个会导致组件什么都不做,从 EAR/lib 中删除一个会导致我的应用不再部署。将所有前端 jar(icefaces.jar、icefaces-ace.jar、icefaces-compat.jar)从 EAR/lib 移动到 WEB-INF/lib 时,我的 EAR 的 jar 部分收到各种 ClassNotFoundExceptions:ValueChangeEvent , RowSelectorEvent 等无法找到(这意味着,所有这些事件都从视图进入后端)。示例:
12:12:42,145 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-16) MSC00001:
Failed to start service jboss.deployment.subunit."myApp.ear"."myApp.jar".POST_MODULE:
org.jboss.msc.service.StartException in service
jboss.deployment.subunit."myApp.ear"."myApp.jar".POST_MODULE: Failed to process phase
POST_MODULE of subdeployment "myApp.jar" of deployment "myApp.ear"
at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:119) [jboss-as-server-7.1.1.Final.jar:7.1.1.Final]
at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) [rt.jar:1.7.0_06]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) [rt.jar:1.7.0_06]
at java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0_06]
Caused by: java.lang.RuntimeException: Error getting reflective information for class my.company.myApp.myExampleBean with ClassLoader ModuleClassLoader for Module "deployment.myApp.ear.myApp.jar:main" from Service Module Loader
at org.jboss.as.server.deployment.reflect.DeploymentReflectionIndex.getClassIndex(DeploymentReflectionIndex.java:70) [jboss-as-server-7.1.1.Final.jar:7.1.1.Final]
at org.jboss.as.ee.metadata.MethodAnnotationAggregator.runtimeAnnotationInformation(MethodAnnotationAggregator.java:58)
at org.jboss.as.ee.component.deployers.InterceptorAnnotationProcessor.handleAnnotations(InterceptorAnnotationProcessor.java:85)
at org.jboss.as.ee.component.deployers.InterceptorAnnotationProcessor.processComponentConfig(InterceptorAnnotationProcessor.java:70)
at org.jboss.as.ee.component.deployers.InterceptorAnnotationProcessor.deploy(InterceptorAnnotationProcessor.java:55)
at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:113) [jboss-as-server-7.1.1.Final.jar:7.1.1.Final]
... 5 more
Caused by: java.lang.NoClassDefFoundError: com/icesoft/faces/component/ext/RowSelectorEvent
at java.lang.Class.getDeclaredMethods0(Native Method) [rt.jar:1.7.0_06]
at java.lang.Class.privateGetDeclaredMethods(Class.java:2442) [rt.jar:1.7.0_06]
at java.lang.Class.getDeclaredMethods(Class.java:1808) [rt.jar:1.7.0_06]
at org.jboss.as.server.deployment.reflect.ClassReflectionIndex.<init>(ClassReflectionIndex.java:65) [jboss-as-server-7.1.1.Final.jar:7.1.1.Final]
at org.jboss.as.server.deployment.reflect.DeploymentReflectionIndex.getClassIndex(DeploymentReflectionIndex.java:66) [jboss-as-server-7.1.1.Final.jar:7.1.1.Final]
... 10 more
Caused by: java.lang.ClassNotFoundException: com.icesoft.faces.component.ext.RowSelectorEvent from [Module "deployment.myApp.ear.myApp.jar:main" from Service Module Loader]
at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:190) [jboss-modules.jar:1.1.1.GA]
at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:468) [jboss-modules.jar:1.1.1.GA]
at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:456) [jboss-modules.jar:1.1.1.GA]
at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:398) [jboss-modules.jar:1.1.1.GA]
at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:120) [jboss-modules.jar:1.1.1.GA]
... 15 more
整个故事
我正在开发一个 Web 应用程序,使用 Seam 2.3 和 ICEfaces 3.1.0。这意味着,正在使用 JSF2。
我的应用程序作为 EAR 部署在 JBoss AS 7.1.0 上,包含一个用于应用程序逻辑的 JAR 和一个用于所有视图相关内容的 WAR。
我最近从 Seam 2.1.2 迁移到 Seam 2.3 和 ICEfaces 1.8.2 到 3.1.0。这一步很糟糕,但现在一切正常,抛开一些小问题。
唯一的大问题是,当我使用组件上传文件时,无论我使用 Seam 组件还是 ICEfaces 组件 - 在 Seam 中,上传的文件始终为空,而在 ICEfaces 中,我的 fileEntryListener-Method 永远不会被调用.
使用 ICEfaces:
在 2.X 之前的 ICEfaces 版本中,ice:inputFile
-组件已被 2.X 删除并替换为 ace:fileEntry
。
InputFile 运行良好,但 FileEntry 没有。我的问题与中描述的完全相同
JSF : Issues with File Upload using Icefaces component - 永远不会调用 fileEntryListener。我在那里尝试了建议(在周围的表单上使用 enctype="multipart/form-data" ,使用h:commandButton
提交表单),但它没有用。提供的唯一解决方案是切换到 Richfaces,这对我来说不是一个选择。
带接缝:
很高兴,Seam 有它自己的内置文件上传组件,s:fileUpload
。
它也不起作用,但至少向我展示了一个可以进一步观察的地方。在调试这个组件的doDecode-Methods时,发现我的请求没有MultipartRequest。疯狂的事!所有用于上传文件的表单都将 enctype 声明为 multipart/form-data。我认为,当我尝试使用 ICEfaces 组件时也会发生同样的情况 - 没有多部分请求,这会导致没有调用任何侦听器。
那么:我该如何让它发挥作用?没有请求作为 MultipartRequest 进来有什么意义?我是否错过了 web/components.xml 中的某些内容?
web.xml:
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xmlns/
javaee/web-app_3_0.xsd"
version="3.0">
<listener>
<listener-class>org.jboss.seam.servlet.SeamListener</listener-class>
</listener>
<filter>
<filter-name>Seam Filter</filter-name>
<filter-class>org.jboss.seam.servlet.SeamFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Seam Filter</filter-name>
<url-pattern>*.seam</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/icefaces/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.seam</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Seam Resource Servlet</servlet-name>
<servlet-class>org.jboss.seam.servlet.SeamResourceServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Seam Resource Servlet</servlet-name>
<url-pattern>/seam/resource/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Resource Servlet</servlet-name>
<servlet-class>com.icesoft.faces.webapp.CompatResourceServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Resource Servlet</servlet-name>
<url-pattern>/xmlhttp/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>60</session-timeout>
</session-config>
<context-param>
<param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>facelets.DEVELOPMENT</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>com.icesoft.faces.actionURLSuffix</param-name>
<param-value>.seam</param-value>
</context-param>
<context-param>
<param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
<param-value>-1</param-value>
</context-param>
<context-param>
<param-name>com.icesoft.faces.synchronousUpdate</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>com.icesoft.faces.doJSFStateManagement</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>com.icesoft.faces.standardRequestScope</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>com.icesoft.faces.uploadDirectory</param-name>
<param-value>upload</param-value>
</context-param>
<context-param>
<param-name>javax.faces.VALIDATE_EMPTY_FIELDS</param-name>
<param-value>false</param-value>
</context-param>
components.xml(省略 Seam 2.3 命名空间声明
<core:init jndi-pattern="java:app/myApp/#ejbName" debug="false"
distributable="false" />
<component class="org.jboss.seam.transaction.EjbSynchronizations"
jndi-name="java:app/jboss-seam/EjbSynchronizations" />
<core:manager concurrent-request-timeout="500"
conversation-timeout="90000000" conversation-id-parameter="cid"
parent-conversation-id-parameter="pid" />
<web:hot-deploy-filter url-pattern="*.seam" />
<web:multipart-filter create-temp-files="true"
max-request-size="1000000"
url-pattern="/*"/>
<persistence:managed-persistence-context
name="entityManager" auto-create="true" persistence-unit-jndi-name="java:/myAppEntityManagerFactory" />
<security:identity authenticate-method="#authenticator.authenticate" />
<security:remember-me enabled="true" />
<security:rule-based-permission-resolver
security-rules="#securityRules" />
<drools:rule-base name="securityRules">
<drools:rule-files>
<value>/security.drl</value>
</drools:rule-files>
</drools:rule-base>
<async:quartz-dispatcher />
<factory name="sessionTimeoutSeconds" scope="SESSION"
value="#facesContext.externalContext.getSession(true).getMaxInactiveInterval()" />
<factory name="basePath"
value="#facesContext.externalContext.request.scheme://#facesContext.externalContext.request.serverName:
#facesContext.externalContext.request.serverPort#facesContext.externalContext.request.contextPath" />
<factory name="contextPath"
value="#facesContext.externalContext.request.contextPath" />
示例 JSF 源代码(Seam)
<h:form enctype="multipart/form-data">
<s:decorate>
<s:fileUpload data="#uploadBean.fileData"
contentType="#uploadBean.contentType"
fileName="#uploadBean.fileName" />
<h:commandButton value="Upload File" type="submit" />
</s:decorate>
</h:form>
示例 JSF 源代码(ICEfaces)
<h:form enctype="multipart/form-data">
<ace:fileEntry id="file-entry" relativePath="/files/"
fileEntryListener="#uploadBean.uploadFile"
useSessionSubdir="true" />
<h:commandButton id="submit" type="submit" value="Send File" />
</h:form>
JSF 映射到一个 Seam 组件,其中有一个 byte[] 用于 fileData,而 String 用于 fileName 和 contentType。 fileEntryListener 映射到一个 void 方法,该方法接受 FileEntryEvent
作为输入。
更新
只是为了让您了解最新情况,到目前为止我的发现:
考虑到 BalusC 的回答,我更深入地研究了过滤器的内容。我已经尝试添加/删除 Seam Multipart Filter,但现在我发现当我将它添加到 components.xml 并通过显式 disable 它时
<web:multipart-filter disabled="true"/>
至少 ICEfaces 发生了一些事情:FileEntryPhaseListener 抛出异常,这是以前从未发生过的:
09:26:19,124 严重 [javax.enterprise.resource.webcontainer.jsf.context] (http- localhost-127.0.0.1-8080-2) JSF1071: javax.faces.event.AbortProcessingException erfasst während beforePhase()-Verarbeitung von RENDER_RESPONSE 6 : UIComponent-ClientId=, Message=/ 模板/患者/文档/实例化/documentInsertPopup.xhtml @135,98 fileEntryListener="#uploadBean.fileUploadListener": 找不到方法: my.company.package.stuff.UploadBean@313d 62f1.fileUploadListener(org.icefaces.ace.component.fileentry.FileEntryEvent) 09:26:19,126 严重 [javax.enterprise.resource.webcontainer.jsf.context] (http- localhost-127.0.0.1-8080-2) /template/upload.xhtml @135,98 fileEntryListener="# uploadBean.fileUploadListener”:找不到方法: my.company.package.stuff.UploadBean@313d 62f1.fileUploadListener(org.icefaces.ace.component.fileentry.FileEntryEvent): javax.faces.event.AbortProcessingException: /upload.xhtml @135,98 fileEntryListener="# uploadBean.fileUploadListener”:找不到方法: my.company.package.stuff.UploadBean@313d 62f1.fileUploadListener(org.icefaces.ace.component.fileentry.FileEntryEvent) 在 org.icefaces.ace.component.fileentry.FileEntry.broadcast(FileEntry.java:350) [icefaces-ace.jar:] 在 org.icefaces.ace.component.fileentry.FileEntryPhaseListener$1.visit(FileEntryPhaseListener.java:95) [icefaces-ace.jar:] 在 com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183) [javax.faces.jar:2.1.4-FCS] 在 javax.faces.component.UIComponent.visitTree(UIComponent.java:1612) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] 在 javax.faces.component.UIComponent.visitTree(UIComponent.java:1623) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] 在 javax.faces.component.UIComponent.visitTree(UIComponent.java:1623) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] 在 javax.faces.component.UIComponent.visitTree(UIComponent.java:1623) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] 在 javax.faces.component.UIComponent.visitTree(UIComponent.java:1623) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] 在 javax.faces.component.UIComponent.visitTree(UIComponent.java:1623) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] 在 javax.faces.component.UIComponent.visitTree(UIComponent.java:1623) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] 在 javax.faces.component.UIForm.visitTree(UIForm.java:371) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] 在 javax.faces.component.UIComponent.visitTree(UIComponent.java:1623) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] 在 javax.faces.component.UIComponent.visitTree(UIComponent.java:1623) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] 在 org.icefaces.ace.component.fileentry.FileEntryPhaseListener.beforePhase(FileEntryPhaseListener.java:100) [icefaces-ace.jar:] 在 com.sun.faces.lifecycle.Phase.handleBeforePhase(Phase.java:228) [javax.faces.jar:2.1.4-FCS] 在 com.sun.faces.lifecycle.Phase.doPhase(Phase.java:99) [javax.faces.jar:2.1.4-FCS] 在 com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139) [javax.faces.jar:2.1.4-FCS] 在 javax.faces.webapp.FacesServlet.service(FacesServlet.java:594) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.13.Final.jar:] 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:] 在 org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83) [jboss-seam.jar:2.3.0.Final] 在 org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:60) [jboss-seam.jar:2.3.0.Final] 在 org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) [jboss-seam.jar:2.3.0.Final] 在 org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64) [jboss-seam.jar:2.3.0.Final] 在 org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) [jboss-seam.jar:2.3.0.Final] 在 org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45) [jboss-seam.jar:2.3.0.Final] 在 org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) [jboss-seam.jar:2.3.0.Final] 在 org.jboss.seam.web.IdentityFilter.doFilter(IdentityFilter.java:40) [jboss-seam.jar:2.3.0.Final] 在 org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) [jboss-seam.jar:2.3.0.Final] 在 org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158) [jboss-seam.jar:2.3.0.Final] 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.13.Final.jar:] 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:] 在 org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [jbossweb-7.0.13.Final.jar:] 在 org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [jbossweb-7.0.13.Final.jar:] 在 org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50) [jboss-as-jpa-7.1.1.Final.jar:7.1.1.Final] 在 org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final] 在 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.13.Final.jar:] 在 org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.13.Final.jar:] 在 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.13.Final.jar:] 在 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) [jbossweb-7.0.13.Final.jar:] 在 org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [jbossweb-7.0.13.Final.jar:] 在 org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671) [jbossweb-7.0.13.Final.jar:] 在 org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930) [jbossweb-7.0.13.Final.jar:] 在 java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0_06]至少这是值得一看的。如果我使用 fileEntryListener 像
fileEntryListener="#uploadBean.fileUploadListener"
如果我使用,则会引发上述异常:
fileEntryListener="#uploadBean.fileUploadListener()"
它抱怨该方法需要参数,如果我像这样使用它:
fileEntryListener="#uploadBean.fileUploadListener(null)"
没有抛出异常,但由于事件为空,没有文件到达我的 UploadBean。闻起来像一些图书馆的问题,但至少还有其他值得一看的地方。
上传 bean
这里没有发生太多事情,只是:
@Stateful
@Name("uploadBean")
@Scope(ScopeType.SESSION)
@JndiName(value = "java:app/myApp.jar/UploadBean")
public class UploadBean implements IUploadBean
public void fileUploadListener(FileEntryEvent event)
System.out.println("listener called!");
监听器也在 bean 的接口中声明。
【问题讨论】:
你能发布你的UploadBean
课程(icefaces 支持的版本)吗?错误似乎很简单:在 bean 上找不到侦听器方法。请注意,该方法必须返回 void
并具有单个 FileEntryEvent
参数。如果缺少其中任何一个,将找不到该方法。在你的标签上,使用fileEntryListener="#uploadBean.fileUploadListener"
版本,不要放括号。
是的,它绝对可用,请参阅更新。 parantheses-stuff 只是为了让它至少做一些事情,在我的应用程序中的所有其他情况下,它可以在没有这些和 ActionEvents、ValueChangeEvents 或任何应该给应用程序的情况下工作。
【参考方案1】:
也许会有所帮助。我所做的是将我的耳朵项目重新部署为战争。
删除 web.xml 中的多部分过滤并将其添加到 components.xml:
<web:multipart-filter disabled="true"/>
我的组件示例:
<ace:panel id="pnl">
<h:form>
<ice:panelGrid columns="2" bgcolor="#0063AA">
<ace:fileEntry id="file-entry" useOriginalFilename="true" immediate="true"
required="true" requiredMessage="The file is required to submit this form."
fileEntryListener="#imageHome.sampleListener"/>
<h:commandButton type="submit" value="Upload" />
</ice:panelGrid>
</h:form>
</ace:panel>
我的 FileEntryEvent 已被调用。
【讨论】:
【参考方案2】:我不使用 Seam,但我注意到我定义为 JSF bean 的 bean 使用的注释与您使用的不同。
对于 bean,我使用 @ManagedBean。 对于范围,我使用@SessionScoped。
【讨论】:
Name 和 Scope 注释是 Seam 的说法:“我是一个会话范围的托管 bean”,所以这里一切正常 :-)【参考方案3】:我仍在调查此问题,但看起来像
<web:multipart-filter disabled="true" url-pattern="bleh"/>
在我的测试用例 components.xml 中没有按预期工作,但是
<component class="org.jboss.seam.web.MultipartFilter">
<property name="disabled">true</property>
</component>
正在努力禁用接缝 MultipartFilter。
【讨论】:
需要禁用多部分过滤器才能使 fileEntry-component 工作。您的选项与 bot 等效,但对于 web:-Part 您必须包含正确的命名空间 - 至少对我而言,它们都有效。 我相信我们要么需要为 ace:fileEntry 添加 POJO 变体(这是 ICEmobile 采用的方法,文件上传“值”是包含“文件”=java.io.File 的 Map和 "type"=String content-type) 或将 icefaces-ace.jar 拆分为 api 和 impl。我个人赞成 POJO 变体,因为很少使用自定义类型,而且 POJO bean 通常更容易使用。【参考方案4】:首先是一些技术背景信息:在即将到来的 JSF 2.2 之前,JSF 本身并不支持 multipart/form-data
请求。所以提供文件上传组件的组件库必须自己提供一个自定义的Filter
。这应该正确解析multipart/form-data
请求并将所有必要的常规数据存储在 HTTP 请求参数映射和上传的文件中作为请求属性。这样,JSF 可以继续使用request.getParameter()
来处理常规数据,并且组件库本身可以获取上传的文件作为请求属性。
如果是 Seam 的 <s:fileUpload>
,您需要 org.jboss.seam.web.MultipartFilter
来执行 multipart/form-data
解析工作。我从来没有使用过 Seam(也没有 ICEfaces),但Google 告诉我你基本上在 webapp 的web.xml
中需要这个@
<filter>
<filter-name>Seam Multipart Filter</filter-name>
<filter-class>org.jboss.seam.web.MultipartFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Seam Multipart Filter</filter-name>
<url-pattern>*.seam</url-pattern>
</filter-mapping>
或者这个在 Seam components.xml
:
<web:multipart-filter url-pattern="*.seam" />
ICEfaces 组件必须配置类似的过滤器。缺少 ICEfaces 3.x 文档(或者我的 Google/icefaces.com 搜索技能不好),所以我无法详细说明这一点。
需要记住的重要一点是,一个 HTTP 请求只能被解析一次(客户端只会发送一次,而不是多次),因此您不能在同一个请求上同时使用两个 multipart/form-data
解析器。 在第一个之后启动的那个会得到一个空的请求体,它不能解析成任何合理的东西。因此,如果您使用的组件正在使用后一种过滤器,那么您将不会在模型中得到任何东西。确保您没有意外或通过实验配置两者。
【讨论】:
感谢您的建议 - 我已经尝试了 Seam Multipart Filter 的东西,但没有成功,但在您发表评论后,我更深入地查看了我的过滤器声明,发现在添加多部分过滤器后禁用它最少让 ICEfaces 做某事 - 请参阅有问题的更新。 确认一下,你的UploadBean
真的有fileUploadListener(FileEntryEvent event)
这个方法吗?例外情况是缺少此方法。顺便说一句,您的 EL 表达式很好,event
将自动提供。鉴于 ICEfaces 在禁用 Seam 过滤器的情况下神奇地工作,它看起来很像它隐式且无声地注册文件上传过滤器。如果您更喜欢使用 Seam 的过滤器,您可能需要查看 ICEfaces 文档(如果某些上下文参数无法禁用该过滤器)——这样您就可以在必要时测试 Seam 一个。
是的,确实如此。在我的应用程序中的所有其他情况下,事件会自动填充侦听器调用,只有 FileEntryEvent 不想......例如如果我使用 null 参数调用侦听器,则会调用它并打印出上述消息,因此至少该方法在某处可用。我想我会在 ICEfaces 上搜索引发事件的地方,看看它去了哪里,也许这会有所帮助......
回到你关于类加载问题的更新;这可以解释它。类加载器X加载的FileEntryEvent
类与类加载器Y加载的FileEntryEvent
类不一样。EL通过类加载器X创建FileEntryEvent
参数和使用上传方法的托管bean类是非常合理的是通过类加载器 Y 加载的。这样方法签名将永远不会匹配。前端库(ICEfaces/Seam/etc)不属于EAR/lib,必须在WEB-INF/lib。因此,如果您修复该部分,上传可能会正常工作。
换句话说,你不应该在类路径的不同位置有同一个库的重复。您提到从 EAR/lib 中删除它时它没有部署。你有具体的异常/错误吗?以上是关于ICEfaces/Seam 文件上传组件不上传文件的主要内容,如果未能解决你的问题,请参考以下文章