无法让CXF JAX-RS和JSF协同工作

时间:2013-04-25 04:26:47

标签: jsf cxf jax-rs apache-tomee facesservlet

我正在尝试设置一个使用CXF JAX-RS和JSF的小型示例应用程序FooTest。我从CXF部分开始,实现了一个简单的服务(工作)和一个名为home.html的小html页面(我可以在我的浏览器中访问它)。相关代码如下:

的web.xml

<servlet>
    <servlet-name>RestServlet</servlet-name>
    <servlet-class>org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet</servlet-class>
    <init-param>
        <param-name>jaxrs.serviceClasses</param-name>
        <param-value>com.test.FooService</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>RestServlet</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

FooService.java

@Path("/rest")
public class FooService {    
    @Path("/foo")
    @GET
    @Produces("application/json; charset=UTF-8")
    public String getFoo() {
        // returns json
    }
}

现在我可以致电http://localhost:8080/FooTest/rest/foohttp://localhost:8080/FooTest/home.html。但是,当我开始定义并将FacesServlet映射到*.html并尝试访问home.html时,我得到NullPointerException

新建web.xml

<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>*.html</url-pattern>
</servlet-mapping>
... CXF stuff ...

导致

Apr 25, 2013 6:08:17 AM org.apache.catalina.core.ApplicationDispatcher invoke
SEVERE: Servlet.service() for servlet Faces Servlet threw exception
java.lang.NullPointerException
    at org.apache.myfaces.shared.context.flash.FlashImpl.isKeepMessages(FlashImpl.java:388)
    at org.apache.myfaces.shared.context.flash.FlashImpl._saveMessages(FlashImpl.java:665)
    at org.apache.myfaces.shared.context.flash.FlashImpl.doPostPhaseActions(FlashImpl.java:269)
    at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:254)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:199)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:749)
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:487)
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:412)
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:339)
    at org.apache.myfaces.context.servlet.ServletExternalContextImpl.dispatch(ServletExternalContextImpl.java:369)
    at org.apache.myfaces.view.jsp.JspViewDeclarationLanguage.buildView(JspViewDeclarationLanguage.java:99)
    at org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderResponseExecutor.java:78)
    at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:241)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:199)
    ... infinite loop from FacesServlet:199 on ...

我该如何解决这个问题?

更新 - 更多配置信息

该应用程序在TomEE 1.5.2的JAX-RS版本上运行。

的src /主/ web应用/ WEB-INF / faces-config.xml中

<?xml version="1.0" encoding="UTF-8"?>
<faces-config 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/xml/ns/javaee/web-facesconfig_2_1.xsd"
    version="2.1">

</faces-config>

更新 - 解决方案

(感谢David Blevins澄清并指出了一个有用的例子)

删除CXF配置部分,不是必需的。将home.html重命名为home.xhtml,因为.xhtml是JSF页面的javax.faces.DEFAULT_SUFFIX。如果要使用FacesServlet扩展名访问JSF页面,请保留.html映射。这就足够了:

<?xml version="1.0" encoding="UTF-8"?>
<web-app ... >
    <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>*.html</url-pattern>
    </servlet-mapping>
</web-app>

1 个答案:

答案 0 :(得分:1)

不确定这应该是评论还是答案,但是你不应该在你的web.xml中设置CXFNonSpringJaxrsServletFacesServlet,所有这些东西都准备好了。 TomEE的目标是您可以跳过服务器构建并直接进入应用程序构建。

CXF完全集成到TomEE中的Tomcat中,甚至WS-Security也可以在Tomcat Realms上运行。您只需添加@ApplicationPath带注释的组件或带有@Path注释的EJB即可开始使用它们,它们将被自动拾取和部署。

MyFaces很适合与CDI完全集成,因此即使像@ConversationScoped这样的东西也可以开箱即用。您只需要faces-config.xml或某些@ManagedBean类。