JSF2 的资源处理程序问题 + Richfaces4 + SpringMVC +网页流 (SWF)

发布于 2024-10-10 07:26:08 字数 4648 浏览 5 评论 0原文

我已经尝试让上述设置工作好几天了,但收效甚微。我的问题似乎与资源处理程序有关。 IE。

<h:outputStylesheet name="header.css" library="page"/>

不起作用,RichFaces 也无法解析其内部使用的任何资源。所以我做了一些调查,上面的标签应该解析为“/project/javax.faces.resource/header.css?ln=page”,但事实并非如此。出现了 2 个明显的问题。

1) 资源处理程序链中的某些内容(可能是 richfaces 处理程序)期望将“.jsf”后缀添加到请求的 url 中,这在使用带有 JSF2 和 JSF2 的旧 EXTERNAL Facelets 时确实会发生。 RichFaces 3.3.x,但带有 Richfaces 4 和不会发生的内置facelets。结果,其中一个处理程序(我相信是 RichFaces)正在剥离 .css 后缀,认为它是一个额外的后缀,就像它以前的工作方式一样。 (因此,这会导致丢失 MIME 类型错误)

2) 当库 & name 属性被解析,它们在当前路径下解析,而不是在 servlet 上下文根下解析。 IE。它应该解析为“/project/javax.faces.resource/...”,但当查看 /index 目录中的页面时,它会解析为“/project/index/javax.faces.resource/...”。

有人可以在这里给我一些见解吗?我正在用头撞墙。没有取得任何真正的基础。

顺便说一句,这是我的基本配置......

faces-config.xml

<application>
    <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>

web.xml

<servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.jsf</url-pattern>
</servlet-mapping>

<servlet>
    <servlet-name>Spring MVC Servlet</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>Spring MVC Servlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

servlet-context.xml

<beans:bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    <beans:property name="viewClass" value="org.springframework.faces.mvc.JsfView"/>
    <beans:property name="prefix" value="/WEB-INF/content/" />
    <beans:property name="suffix" value=".xhtml" />
</beans:bean>

<beans:bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
        <beans:property name="order" value="2"/>
        <beans:property name="flowRegistry" ref="flowRegistry" />
</beans:bean>

<beans:bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter">
    <beans:property name="flowExecutor" ref="flowExecutor" />
    <beans:property name="ajaxHandler">
        <beans:bean class="org.springframework.faces.richfaces.RichFacesAjaxHandler"/>
    </beans:property>
</beans:bean>

<beans:bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    <beans:property name="viewClass" value="org.springframework.faces.mvc.JsfView"/>
    <beans:property name="prefix" value="/WEB-INF/content/" />
    <beans:property name="suffix" value=".xhtml" />
</beans:bean>


<beans:bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
<beans:bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <beans:property name="order" value="3" />
    <beans:property name="alwaysUseFullPath" value="true" />
    <beans:property name="mappings">
        <beans:value>
        </beans:value>
    </beans:property>
    <beans:property name="defaultHandler">
        <beans:bean class="org.springframework.web.servlet.mvc.UrlFilenameViewController" />
    </beans:property>
</beans:bean>

webflow-config .xml

<faces:resources/>

<beans:bean id="facesContextListener" class="org.springframework.faces.webflow.FlowFacesContextLifecycleListener"/>

<flow-executor id="flowExecutor">
    <flow-execution-listeners>
        <listener ref="facesContextListener"/>
    </flow-execution-listeners>
</flow-executor>

<flow-registry id="flowRegistry" base-path="/WEB-INF/content" flow-builder-services="flowBuilderServices">
    <flow-location-pattern value="/**/flow.xml" />
</flow-registry>

<flow-builder-services id="flowBuilderServices" development="true" />

I've been trying to get the above mentioned setup working for days now with minimal success. My issues appears to be with the resource handler. Ie.

<h:outputStylesheet name="header.css" library="page"/>

does not work, NOR can RichFaces resolve any of the resources it uses internally. So i've done some investigating and the tag above should be resolving to "/project/javax.faces.resource/header.css?ln=page" but it is not. 2 obvious issues are occuring.

1) Something in the Resource Handler chain, possibly the richfaces handler, is expecting a ".jsf" suffix to be added to the requested url, which does happen when using the old EXTERNAL facelets w/ JSF2 & RichFaces 3.3.x, but with Richfaces 4 & builtin facelets that doesn't take place. As a result, one of the handlers (RichFaces' I believe) is stripping the .css suffix off thinking it's an extra suffix like how it used to work. (Consequently this causes missing MIME type errors)

2) When the library & name attributes are resolved, the are resolved under the current path instead of the servlet context root. Ie. it should be resolving to "/project/javax.faces.resource/..." but instead it resolves to "/project/index/javax.faces.resource/..." when viewing a page in the /index directory.

Can anyone please give me some insight here? I'm banging my head against the wall on this one & not making any real ground.

btw here is my basic config....

faces-config.xml

<application>
    <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>

web.xml

<servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.jsf</url-pattern>
</servlet-mapping>

<servlet>
    <servlet-name>Spring MVC Servlet</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>Spring MVC Servlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

servlet-context.xml

<beans:bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    <beans:property name="viewClass" value="org.springframework.faces.mvc.JsfView"/>
    <beans:property name="prefix" value="/WEB-INF/content/" />
    <beans:property name="suffix" value=".xhtml" />
</beans:bean>

<beans:bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
        <beans:property name="order" value="2"/>
        <beans:property name="flowRegistry" ref="flowRegistry" />
</beans:bean>

<beans:bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter">
    <beans:property name="flowExecutor" ref="flowExecutor" />
    <beans:property name="ajaxHandler">
        <beans:bean class="org.springframework.faces.richfaces.RichFacesAjaxHandler"/>
    </beans:property>
</beans:bean>

<beans:bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    <beans:property name="viewClass" value="org.springframework.faces.mvc.JsfView"/>
    <beans:property name="prefix" value="/WEB-INF/content/" />
    <beans:property name="suffix" value=".xhtml" />
</beans:bean>


<beans:bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
<beans:bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <beans:property name="order" value="3" />
    <beans:property name="alwaysUseFullPath" value="true" />
    <beans:property name="mappings">
        <beans:value>
        </beans:value>
    </beans:property>
    <beans:property name="defaultHandler">
        <beans:bean class="org.springframework.web.servlet.mvc.UrlFilenameViewController" />
    </beans:property>
</beans:bean>

webflow-config.xml

<faces:resources/>

<beans:bean id="facesContextListener" class="org.springframework.faces.webflow.FlowFacesContextLifecycleListener"/>

<flow-executor id="flowExecutor">
    <flow-execution-listeners>
        <listener ref="facesContextListener"/>
    </flow-execution-listeners>
</flow-executor>

<flow-registry id="flowRegistry" base-path="/WEB-INF/content" flow-builder-services="flowBuilderServices">
    <flow-location-pattern value="/**/flow.xml" />
</flow-registry>

<flow-builder-services id="flowBuilderServices" development="true" />

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

人心善变 2024-10-17 07:26:08

好吧,在 Rich Faces 的帮助下,我终于搞定了这个。因此,对于任何有兴趣在 Tomcat6+ 上运行 JSF2 + Rich Faces + SpringMVC + Spring WebFlow 的人来说,这就是您所需要的......

WEB.XML

    <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/config/appServlet/servletContext.xml</param-value>
</context-param>

<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>

<servlet>
    <servlet-name>faces</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>0</load-on-startup>
</servlet>

<servlet>
    <servlet-name>spring</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <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</servlet-name>
    <url-pattern>/app/*</url-pattern>
</servlet-mapping>

<servlet-mapping>
    <servlet-name>faces</servlet-name>
    <url-pattern>*.jsf</url-pattern>
</servlet-mapping>

<context-param>
    <param-name>javax.faces.FACELETS_VIEW_MAPPINGS</param-name>
    <param-value>*.xhtml</param-value>
</context-param>

servletContext.xml

    <mvc:annotation-driven />
    <context:component-scan base-package="com.package.subpackage"/>

<mvc:resources location="/" mapping="/resources/**" />

<faces:resources order="0" />

<bean id="flowHandlerMapping"
    class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
    <property name="flowRegistry" ref="flowRegistry" />
    <property name="order" value="3" />
    <property name="defaultHandler" ref="defaultHandler" />
</bean>

<bean class="org.springframework.faces.webflow.JsfFlowHandlerAdapter">
    <property name="flowExecutor" ref="flowExecutor" />
    <property name="ajaxHandler">
        <bean class="org.springframework.faces.richfaces.RichFacesAjaxHandler" />
    </property>
</bean>

<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    <property name="viewClass" value="org.springframework.faces.mvc.JsfView"/>
    <property name="prefix" value="/WEB-INF/pageContent/" />
    <property name="suffix" value=".xhtml" />
</bean>

< springmvc-config.xml

<bean name="jsfResourceHandlerHack" class="org.springframework.faces.webflow.JsfResourceRequestHandler" />

<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="order" value="1" />
    <property name="mappings">
        <value>
            /rfRes/**=jsfResourceHandlerHack
        </value>
    </property>
</bean>

spring-webflow-config.xml

    <!-- Executes flows: the central entry point into the Spring Web Flow system -->
<flow-executor id="flowExecutor">
    <flow-execution-listeners>
        <listener ref="facesContextListener"/>
    </flow-execution-listeners>
</flow-executor>

<flow-registry id="flowRegistry" base-path="/WEB-INF/content" flow-builder-services="facesFlowBuilderServices">
    <flow-location-pattern value="/**/flow.xml" />
    <flow-location id="parent-flow" path="parent-flow.xml"/>
</flow-registry>

<faces:flow-builder-services id="facesFlowBuilderServices" development="true"/>
<beans:bean name="facesContextListener" class="org.springframework.faces.webflow.FlowFacesContextLifecycleListener" />

spring-beans-config.xml
`

<bean name="defaultHandler" class="org.springframework.web.servlet.mvc.UrlFilenameViewController" >

</bean>`

Jar 版本如下...
弹簧核心3.0.5
Spring Web 流程 2.2.1
JSF 注册机 2.0.3
最重要的是...
Rich Faces 4.0.0.20101226-M5

因此,完成这项工作的关键似乎是 RichFaces 的版本。 RichFaces 4 尚未准备好投入生产,因此希望一旦发生这种情况,一切都会顺利进行,但与此同时,现在 Milestone 5 已经发布了,此设置似乎可以正常工作。需要注意的部分是 JsfResourceHandlerHack 映射。 Richfaces 尝试默认使用关键字“rfRes”解析其某些资源(我相信是即时创建的资源)。我遇到的问题是“rfRes”键没有映射到资源处理程序。有一种方法可以配置它,但似乎不起作用。因此,快速解决方法是创建另一个资源处理程序实例并手动映射它。所以对于任何有兴趣的人来说,它就在那里。

Ok so I FINALLY nailed this one... with a little help from Rich Faces. So for anyone who is interested in running JSF2 + Rich Faces + SpringMVC + Spring WebFlow on Tomcat6+, well here is what you need...

WEB.XML

    <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/config/appServlet/servletContext.xml</param-value>
</context-param>

<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>

<servlet>
    <servlet-name>faces</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>0</load-on-startup>
</servlet>

<servlet>
    <servlet-name>spring</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <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</servlet-name>
    <url-pattern>/app/*</url-pattern>
</servlet-mapping>

<servlet-mapping>
    <servlet-name>faces</servlet-name>
    <url-pattern>*.jsf</url-pattern>
</servlet-mapping>

<context-param>
    <param-name>javax.faces.FACELETS_VIEW_MAPPINGS</param-name>
    <param-value>*.xhtml</param-value>
</context-param>

servletContext.xml

    <mvc:annotation-driven />
    <context:component-scan base-package="com.package.subpackage"/>

<mvc:resources location="/" mapping="/resources/**" />

<faces:resources order="0" />

<bean id="flowHandlerMapping"
    class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
    <property name="flowRegistry" ref="flowRegistry" />
    <property name="order" value="3" />
    <property name="defaultHandler" ref="defaultHandler" />
</bean>

<bean class="org.springframework.faces.webflow.JsfFlowHandlerAdapter">
    <property name="flowExecutor" ref="flowExecutor" />
    <property name="ajaxHandler">
        <bean class="org.springframework.faces.richfaces.RichFacesAjaxHandler" />
    </property>
</bean>

<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    <property name="viewClass" value="org.springframework.faces.mvc.JsfView"/>
    <property name="prefix" value="/WEB-INF/pageContent/" />
    <property name="suffix" value=".xhtml" />
</bean>

springmvc-config.xml

<bean name="jsfResourceHandlerHack" class="org.springframework.faces.webflow.JsfResourceRequestHandler" />

<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="order" value="1" />
    <property name="mappings">
        <value>
            /rfRes/**=jsfResourceHandlerHack
        </value>
    </property>
</bean>

spring-webflow-config.xml

    <!-- Executes flows: the central entry point into the Spring Web Flow system -->
<flow-executor id="flowExecutor">
    <flow-execution-listeners>
        <listener ref="facesContextListener"/>
    </flow-execution-listeners>
</flow-executor>

<flow-registry id="flowRegistry" base-path="/WEB-INF/content" flow-builder-services="facesFlowBuilderServices">
    <flow-location-pattern value="/**/flow.xml" />
    <flow-location id="parent-flow" path="parent-flow.xml"/>
</flow-registry>

<faces:flow-builder-services id="facesFlowBuilderServices" development="true"/>
<beans:bean name="facesContextListener" class="org.springframework.faces.webflow.FlowFacesContextLifecycleListener" />

spring-beans-config.xml
`

<bean name="defaultHandler" class="org.springframework.web.servlet.mvc.UrlFilenameViewController" >

</bean>`

The Jar versions are as follows...
Spring Core 3.0.5
Spring Web Flow 2.2.1
JSF RI 2.0.3
and most importantly...
Rich Faces 4.0.0.20101226-M5

So the key to making this work seemed to be the version of RichFaces. RichFaces 4 is not production ready yet, so hopefully once that happens everything will be working smoothly but in the meantime, now that Milestone 5 has been released, this setup seems to work. The part to take note of is the JsfResourceHandlerHack mapping. Richfaces attempts to resolve some of its resources (the ones created on the fly I believe) using the keyword "rfRes" by default. The problem I had was the "rfRes" key is not being mapped to the resource handler. There is a way to configure it, but that didn't seem to be working. So the quick fix is to create another resource handler instance and map it manually. So for anyone who is interested, there it is.

阳光下慵懒的猫 2024-10-17 07:26:08

I think your question is answered in https://jira.springsource.org/browse/SWF-1366.

Good luck

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文