找不到用于转换“dataModel”的 Faces 转换服务;
在使用 JSF 集成创建我的第一个 swf 应用程序时,出现以下错误:在第一个请求上解析我的流定义时无法加载类“dataModel”。
尽管我的 webflow 应用程序上下文包含
标签。
在尝试找出原因时进行一些调试,我注意到以下内容:
- 包含
的 xml 文件由上下文加载器侦听器加载,并且 facesConversionService bean 被注册, - 流处理程序映射和适配器被正确调用,并且请求被转发到预期的流,该定义是动态创建的。
- 在为流创建内部基础结构对象时,swf 在侦听器加载的应用程序上下文之上创建一个 Web 应用程序上下文。这个新的 wac 包含 swf 范围等的定义,并且将上面的侦听器应用程序上下文作为父级。
- 找到并解析我的流的流定义文件,当它尝试查找评估元素的结果类型的类时,转换服务不知道“dataModel”别名。
实际上,最后一点的有趣之处在于,转换服务要么在上面第 3 点创建的应用程序上下文中作为本地 bean 进行查找,要么在父流构建器上下文中查找(如果未找到)。
面孔转换服务既不是上下文的本地 bean(它注册在流上下文的父上下文中),也不是注册为流构建器上下文的转换服务(至少是由 < code>
有人知道出了什么问题吗?
我不认为它与应用程序服务器有关,但以防万一,我在 websphere 6.1.0.23 上运行,带有 spring 2.5.6 和 webflow 2.0.8.RELEASE。
以下是我的配置文件:
web.xml:
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext-*.xml</param-value>
</context-param>
...
<servlet>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<url-pattern>/swf/*</url-pattern>
</servlet-mapping>
MVC 部分的 Bean 定义 (/WEB-INF/applicationContext-webmvc.xml):swf
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
<property name="flowRegistry" ref="flowRegistry" />
<property name="defaultHandler">
<bean class="org.springframework.web.servlet.mvc.UrlFilenameViewController" />
</property>
</bean>
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter">
<property name="flowExecutor" ref="flowExecutor" />
</bean>
<bean id="faceletsViewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.faces.mvc.JsfView" />
<property name="prefix" value="/WEB-INF/" />
<property name="suffix" value=".jspx" />
</bean>
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
部分的 Bean 定义 (/WEB-INF/applicationContext-webflow.xml):
<flow:flow-registry id="flowRegistry" base-path="/WEB-INF/flows">
<flow:flow-location path="/navigation/navigation.xml"/>
<flow:flow-location path="/edition/edition.xml"/>
</flow:flow-registry>
<flow:flow-executor id="flowExecutor">
<flow:flow-execution-listeners>
<flow:listener ref="jpaFlowExecutionListener" criteria="edition"/>
</flow:flow-execution-listeners>
</flow:flow-executor>
<faces:flow-builder-services id="facesFlowBuilderServices" development="true"/>
<bean id="jpaFlowExecutionListener"
class="org.springframework...JpaFlowExecutionListener">
<constructor-arg ref="entityManagerFactory" />
<constructor-arg ref="transactionManager" />
</bean>
堆栈跟踪异常:
[Servlet Error]-[Spring MVC Dispatcher Servlet]: java.lang.IllegalArgumentException: Unable to load class 'dataModel'
at org.springframework.webflow.engine.builder.model.FlowModelFlowBuilder.toClass(FlowModelFlowBuilder.java:965)
at org.springframework.webflow.engine.builder.model.FlowModelFlowBuilder.parseEvaluationActionResultExposer(FlowModelFlowBuilder.java:867)
at org.springframework.webflow.engine.builder.model.FlowModelFlowBuilder.parseEvaluateAction(FlowModelFlowBuilder.java:858)
at org.springframework.webflow.engine.builder.model.FlowModelFlowBuilder.parseActions(FlowModelFlowBuilder.java:834)
at org.springframework.webflow.engine.builder.model.FlowModelFlowBuilder.parseAndAddViewState(FlowModelFlowBuilder.java:547)
at org.springframework.webflow.engine.builder.model.FlowModelFlowBuilder.buildStates(FlowModelFlowBuilder.java:207)
at org.springframework.webflow.engine.builder.FlowAssembler.directAssembly(FlowAssembler.java:106)
at org.springframework.webflow.engine.builder.FlowAssembler.assembleFlow(FlowAssembler.java:91)
at org.springframework.webflow.engine.builder.DefaultFlowHolder.assembleFlow(DefaultFlowHolder.java:109)
at org.springframework.webflow.engine.builder.DefaultFlowHolder.getFlowDefinition(DefaultFlowHolder.java:84)
at org.springframework.webflow.definition.registry.FlowDefinitionRegistryImpl.getFlowDefinition(FlowDefinitionRegistryImpl.java:61)
at org.springframework.webflow.executor.FlowExecutorImpl.launchExecution(FlowExecutorImpl.java:138)
at org.springframework.webflow.mvc.servlet.FlowHandlerAdapter.handle(FlowHandlerAdapter.java:193)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:807)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:501)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:743)
While creating my first swf application with JSF integration, I get the following error : Unable to load class 'dataModel' when parsing my flow definition on the first request.
It appears that the FacesConversionService (the class that understands the 'dataModel' alias) is not invoked while trying to find a class for that alias, although my webflow application context contains the <faces:flow-builder-services/>
tag in it.
Doing some debug while trying to find out the cause, I noticed the following:
- the xml file containing
<faces:flow-builder-services/>
is loaded by the context loader listener, and the facesConversionService bean is registered - the flow handler mapping and adapter are correctly invoked and the request is forwarded to the expected flow, which definition is created on the fly.
- while creating internal infrastructure objects for the flow, swf creates a web application context on top of the app context loaded by the listener. This new wac contains the definitions for the swf scopes, etc, and has the listener's application context from above as parent.
- the flow definition file for my flow is found and parsed, and when it tries to find the class for the result type of an evaluate element, the conversion service does not know about the 'dataModel' alias.
Actually, the funny thing on the last point is that the conversion service is either looked up as a local bean in the application context created on point 3. above, or -if not found- looked up in the parent flow builder context.
The faces conversion service is neither a local bean of the context (it is registered in the parent context of the flow context), nor is it registered as the conversion service of the flow builder context (at least the FlowBuilderContextImpl that is created by the <flow:flow-registry/>
element).
Does anybody know what went wrong ?
I don't think it's related to the application server, but just in case, I'm running on websphere 6.1.0.23, with spring 2.5.6 and webflow 2.0.8.RELEASE.
Here are my configuration files:
web.xml:
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext-*.xml</param-value>
</context-param>
...
<servlet>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<url-pattern>/swf/*</url-pattern>
</servlet-mapping>
Beans definitions for the MVC part (/WEB-INF/applicationContext-webmvc.xml):
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
<property name="flowRegistry" ref="flowRegistry" />
<property name="defaultHandler">
<bean class="org.springframework.web.servlet.mvc.UrlFilenameViewController" />
</property>
</bean>
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter">
<property name="flowExecutor" ref="flowExecutor" />
</bean>
<bean id="faceletsViewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.faces.mvc.JsfView" />
<property name="prefix" value="/WEB-INF/" />
<property name="suffix" value=".jspx" />
</bean>
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
Beans definitions for the swf part (/WEB-INF/applicationContext-webflow.xml):
<flow:flow-registry id="flowRegistry" base-path="/WEB-INF/flows">
<flow:flow-location path="/navigation/navigation.xml"/>
<flow:flow-location path="/edition/edition.xml"/>
</flow:flow-registry>
<flow:flow-executor id="flowExecutor">
<flow:flow-execution-listeners>
<flow:listener ref="jpaFlowExecutionListener" criteria="edition"/>
</flow:flow-execution-listeners>
</flow:flow-executor>
<faces:flow-builder-services id="facesFlowBuilderServices" development="true"/>
<bean id="jpaFlowExecutionListener"
class="org.springframework...JpaFlowExecutionListener">
<constructor-arg ref="entityManagerFactory" />
<constructor-arg ref="transactionManager" />
</bean>
The stack trace for the exception:
[Servlet Error]-[Spring MVC Dispatcher Servlet]: java.lang.IllegalArgumentException: Unable to load class 'dataModel'
at org.springframework.webflow.engine.builder.model.FlowModelFlowBuilder.toClass(FlowModelFlowBuilder.java:965)
at org.springframework.webflow.engine.builder.model.FlowModelFlowBuilder.parseEvaluationActionResultExposer(FlowModelFlowBuilder.java:867)
at org.springframework.webflow.engine.builder.model.FlowModelFlowBuilder.parseEvaluateAction(FlowModelFlowBuilder.java:858)
at org.springframework.webflow.engine.builder.model.FlowModelFlowBuilder.parseActions(FlowModelFlowBuilder.java:834)
at org.springframework.webflow.engine.builder.model.FlowModelFlowBuilder.parseAndAddViewState(FlowModelFlowBuilder.java:547)
at org.springframework.webflow.engine.builder.model.FlowModelFlowBuilder.buildStates(FlowModelFlowBuilder.java:207)
at org.springframework.webflow.engine.builder.FlowAssembler.directAssembly(FlowAssembler.java:106)
at org.springframework.webflow.engine.builder.FlowAssembler.assembleFlow(FlowAssembler.java:91)
at org.springframework.webflow.engine.builder.DefaultFlowHolder.assembleFlow(DefaultFlowHolder.java:109)
at org.springframework.webflow.engine.builder.DefaultFlowHolder.getFlowDefinition(DefaultFlowHolder.java:84)
at org.springframework.webflow.definition.registry.FlowDefinitionRegistryImpl.getFlowDefinition(FlowDefinitionRegistryImpl.java:61)
at org.springframework.webflow.executor.FlowExecutorImpl.launchExecution(FlowExecutorImpl.java:138)
at org.springframework.webflow.mvc.servlet.FlowHandlerAdapter.handle(FlowHandlerAdapter.java:193)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:807)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:501)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:743)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我忘记在 flow:flow-registry 元素上指定 flow-builder-services 属性!!!现在工作完美。
I forgot to specify the flow-builder-services attribute on flow:flow-registry element !!! Works perfectly now.
我遇到了同样的问题,但这是因为我指定了自己的转换服务,该服务扩展了
DefaultConversionService
而不是FacesConversionService
。I had the same problem but it was because I was specifying my own conversion service which extended
DefaultConversionService
rather thanFacesConversionService
.