0

更新

我试图在我的 spring3 应用程序中使用 JSF 复合组件。做一个简单的测试

/test(映射到视图视图\test.xhtml)

我收到以下错误:

  org.springframework.web.util.NestedServletException: Request processing failed; nested exception is javax.faces.FacesException
     org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:656)
     org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
     javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
     javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
  causa raíz

  javax.faces.FacesException
     com.sun.faces.context.ExceptionHandlerImpl.handle(ExceptionHandlerImpl.java:141)
     com.sun.faces.lifecycle.Phase.doPhase(Phase.java:119)
     com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
     org.springframework.faces.mvc.JsfView.renderMergedOutputModel(JsfView.java:85)
     org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
     org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1047)
     org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:817)
     org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
     org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
     org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
     javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
     javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
  causa raíz

  java.lang.NullPointerException
     com.sun.faces.application.ApplicationImpl.createComponent(ApplicationImpl.java:972)
     org.springframework.faces.webflow.Jsf2FlowApplication.createComponent(Jsf2FlowApplication.java:68)
     com.sun.faces.facelets.tag.jsf.CompositeComponentTagHandler.createComponent(CompositeComponentTagHandler.java:165)
     com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.createComponent(ComponentTagHandlerDelegateImpl.java:488)
     com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:157)
     javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120)
     javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:98)
     com.sun.faces.facelets.tag.ui.DefineHandler.applyDefinition(DefineHandler.java:103)
     com.sun.faces.facelets.tag.ui.CompositionHandler.apply(CompositionHandler.java:178)
     com.sun.faces.facelets.impl.DefaultFaceletContext$TemplateManager.apply(DefaultFaceletContext.java:395)
     com.sun.faces.facelets.impl.DefaultFaceletContext.includeDefinition(DefaultFaceletContext.java:366)
     com.sun.faces.facelets.tag.ui.InsertHandler.apply(InsertHandler.java:108)
     javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:98)
     javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandler.java:137)
     com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:188)
     javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120)
     javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:98)
     com.sun.faces.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:93)
     javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:98)
     com.sun.faces.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:86)
     com.sun.faces.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:308)
     com.sun.faces.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:367)
     com.sun.faces.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:346)
     com.sun.faces.facelets.impl.DefaultFaceletContext.includeFacelet(DefaultFaceletContext.java:199)
     com.sun.faces.facelets.tag.ui.CompositionHandler.apply(CompositionHandler.java:155)
     com.sun.faces.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:93)
     com.sun.faces.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:86)
     com.sun.faces.facelets.impl.DefaultFacelet.apply(DefaultFacelet.java:152)
     com.sun.faces.application.view.FaceletViewHandlingStrategy.buildView(FaceletViewHandlingStrategy.java:769)
     com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:100)
     com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
     com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
     org.springframework.faces.mvc.JsfView.renderMergedOutputModel(JsfView.java:85)
     org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
     org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1047)
     org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:817)
     org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
     org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
     org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
     javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
     javax.servlet.http.HttpServlet.service(HttpServlet.java:728)

如果我删除复合组件,此错误就会消失

这是我的文件树

 \
 +src

 |   +main
 |      +java
 |      |  \(...)
        |      \CustomResourceHandler.java
 |      +resources
 |      |  +META-INF
 |      |  +applicationContext.xml
 |      |  \(...)
 |      \webapp
 |         +(...)
 |         +resources
 |         |  \ui
 |         |    \util
 |         |      \hello.xhtml
 |         +WEB-INF
 |         |  \views
 |         |     \test.xhtml
 |         +faces-config.xml
 |         \web.xml
 \pom.xml

你好.xhtml

  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  <html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:composite="http://java.sun.com/jsf/composite"
    xmlns:h="http://java.sun.com/jsf/html">
          <composite:interface>
          </composite:interface>

          <composite:implementation>
             <h:outputText value="hello composite" />
          </composite:implementation>
  </html>

测试.xhtml

  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

  <html xmlns="http://www.w3.org/1999/xhtml"
        xmlns:ui="http://java.sun.com/jsf/facelets"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:util="http://java.sun.com/jsf/composite/ui/util">



  <util:hello/>


  </html>

应用程序上下文.xml

  <?xml version="1.0" encoding="UTF-8"?>
  <beans xmlns="http://www.springframework.org/schema/beans"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:context="http://www.springframework.org/schema/context"
         xmlns:aop="http://www.springframework.org/schema/aop"
         xmlns:tx="http://www.springframework.org/schema/tx"
         xmlns:mvc="http://www.springframework.org/schema/mvc"
         xmlns:p="http://www.springframework.org/schema/p"

         xsi:schemaLocation="
          http://www.springframework.org/schema/beans 
          http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
          http://www.springframework.org/schema/context 
          http://www.springframework.org/schema/context/spring-context-3.0.xsd
          http://www.springframework.org/schema/tx 
          http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
          http://www.springframework.org/schema/aop 
          http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
          http://www.springframework.org/schema/mvc
          http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

     <!-- holding properties for database connectivity /-->
      <context:property-placeholder location="classpath:jdbc.properties"/>


      <context:component-scan base-package="........" />
      <context:component-scan base-package="........"/>

      <!-- map all requests to /resources/** to the container default servlet (ie, don't let Spring handle them) -->

      <bean id="defaultServletHttpRequestHandler" class="org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler" />

      <bean id="simpleUrlHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
          <property name="urlMap">
          <map>
              <entry key="/resources/**" value-ref="defaultServletHttpRequestHandler" />
              <entry key="/javax.faces.resource/**" value-ref="defaultServletHttpRequestHandler" />
          </map>
          </property>
      </bean>

      <bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter" />

      <mvc:annotation-driven/>
      <bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
          <property name="cache" value="false" />
          <property name="viewClass" value="org.springframework.faces.mvc.JsfView" />
          <property name="prefix" value="/WEB-INF/views/" />
          <property name="suffix" value=".xhtml" />
      </bean>
      <context:annotation-config/>


      <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username"  value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
      </bean>

      <bean id="entityManagerFactory"
     class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
     p:dataSource-ref="dataSource"
     p:jpaVendorAdapter-ref="jpaAdapter">
     <property name="loadTimeWeaver">
            <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
          </property>                             
          <property name="persistenceUnitName" value="....."></property>
      </bean>

      <bean id="jpaAdapter"
     class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
     p:database="${jpa.database}"
     p:showSql="${jpa.showSql}"/>

      <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
     p:entityManagerFactory-ref="entityManagerFactory"/>
  </beans>

面孔-config.xml

  <?xml version="1.0" encoding="UTF-8"?>

  <faces-config version="2.0" 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_0.xsd">

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

          <resource-handler>....***.CustomResourceHandler</resource-handler>

          <locale-config>
          </locale-config>

          <resource-bundle>
              <base-name>compass</base-name>
              <var>txt</var>
          </resource-bundle>
      </application>
  </faces-config>

web.xml

  <?xml version="1.0" encoding="UTF-8"?>
  <web-app version="2.5" 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-app_2_5.xsd">
     <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
     </context-param>


     <context-param>
        <param-name>log4jConfigLocation</param-name>
        <param-value>classpath:log4j.xml</param-value>
     </context-param>

     <listener>
        <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</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
     </servlet>
     <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
           <param-name>contextConfigLocation</param-name>
           <param-value>classpath:applicationContext.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
     </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>*.xhtml</url-pattern>
     </servlet-mapping>
     <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
     </servlet-mapping>


  </web-app>

CustomResourceHandler.java

  import javax.faces.application.Resource;
  import javax.faces.application.ResourceHandler;
  import javax.faces.application.ResourceHandlerWrapper;
  import javax.faces.application.ResourceWrapper;
  import javax.faces.context.FacesContext;

  import com.sun.faces.util.Util;

  /**
   * Custom JSF ResourceHandler.
   * 
   * This handler bridges between Spring MVC and JSF managed resources. The handler takes
   * care of the case when a JSF facelet is used as a view by a Spring MVC Controller and the
   * view uses components like h:outputScript and h:outputStylesheet by correctly pointing the 
   * resource URLs generated to the JSF resource handler.
   * 
   * The reason this custom handler wrapper is needed is because the JSF internal logic assumes
   * that the request URL for the current page/view is a JSF url. If it is a Spring MVC request, JSF
   * will create URLs that incorrectly includes the Spring controller context.
   * 
   * This handler will strip out the Spring context for the URL and add the ".jsf" suffix, so the
   * resource request will be routed to the FacesServlet with a correct resource context (assuming the
   * faces servlet is mapped to the *.jsf pattern). 
   * 
   *
   */
  public class CustomResourceHandler extends ResourceHandlerWrapper {

      private ResourceHandler wrapped;

      public CustomResourceHandler(ResourceHandler wrapped) {
          this.wrapped = wrapped;
      }
      @Override
      public ResourceHandler getWrapped() {
          return this.wrapped;    
      }

      @Override
      public Resource createResource(String resourceName, String libraryName) {
          return new CustomResource(super.createResource(resourceName, libraryName),resourceName);
      }
      @Override
      public Resource createResource(String resourceName, String libraryName,
              String contentType) {
        return new CustomResource(super.createResource(resourceName, libraryName, contentType),resourceName);
      }

      private static class CustomResource extends ResourceWrapper {

          private Resource wrapped;
          private String resourceName;

          private CustomResource(Resource wrapped,String resourceName) {
           //super();
           this.resourceName = resourceName;
              this.wrapped = wrapped;
          }
          @Override
          public Resource getWrapped() {
              return this.wrapped;
          }
          @Override
          public String getRequestPath() {
           FacesContext context = FacesContext.getCurrentInstance();

           // si no existe el recurso lo mapeamos igualmente 
           if (this.wrapped == null) {
              return  context.getExternalContext().getRequestContextPath() + "/resources/" + resourceName;
           }
           String path = super.getRequestPath();

              String facesServletMapping = Util.getFacesMapping(context);
              // if prefix-mapped, this is a resource that is requested from a faces page
              // rendered as a view to a Spring MVC controller.
              // facesServletMapping will, in fact, be the Spring mapping
              if (Util.isPrefixMapped(facesServletMapping)) {
                  // remove the Spring mapping
                  path = path.replaceFirst("(" + facesServletMapping + ")/", "/");
                  // append .jsf to route this URL to the FacesServlet
                  path = path.replace(wrapped.getResourceName(), wrapped.getResourceName() + ".jsf");
              }
              return path;
          }

      }
  }

pom.xml

  <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <groupId>****</groupId>
     <artifactId>****/artifactId>
     <version>0.0.1</version>
     <packaging>war</packaging>
     <name>****</name>
     <properties>
        <org.springframework.version>3.0.5.RELEASE</org.springframework.version>
        <org.hibernate.version>3.5.1-Final</org.hibernate.version>
        <maven.compiler.source>1.6</maven.compiler.source>
        <maven.compiler.target>1.6</maven.compiler.target>
        <com.sun.faces.version>2.1.1-b04</com.sun.faces.version>
        <!--  2.0.4-b09 -->
     </properties>
     <repositories>
        <repository>
           <!-- Crear este repositorio con nexus para hostear los jar de terceros -->
           <id>terceros</id>
           <name>Repositorio Local</name>
           <url>http://127.0.0.1:8081/nexus/content/repositories/thirdparty</url>
        </repository>
        <repository>
           <id>repository.jboss.org-public</id>
           <name>JBoss repository</name>
           <url>https://repository.jboss.org/nexus/content/groups/public</url>
        </repository>
     </repositories>
     <dependencies>
        <dependency>
           <groupId>log4j</groupId>
           <artifactId>log4j</artifactId>
           <version>1.2.16</version>
        </dependency>
        <dependency>
           <groupId>org.springframework.security</groupId>
           <artifactId>spring-security-config</artifactId>
           <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
           <groupId>org.springframework.security</groupId>
           <artifactId>spring-security-core</artifactId>
           <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
           <groupId>org.springframework.security</groupId>
           <artifactId>spring-security-ldap</artifactId>
           <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
           <groupId>org.springframework.security</groupId>
           <artifactId>spring-security-taglibs</artifactId>
           <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
           <groupId>org.springframework.security</groupId>
           <artifactId>spring-security-web</artifactId>
           <version>${org.springframework.version}</version>
        </dependency>

        <dependency>
           <groupId>com.sun.faces</groupId>
           <artifactId>jsf-api</artifactId>
           <version>${com.sun.faces.version}</version>
        </dependency>

        <dependency>
           <groupId>com.sun.faces</groupId>
           <artifactId>jsf-impl</artifactId>
           <version>${com.sun.faces.version}</version>
        </dependency>

        <dependency>
           <groupId>org.slf4j</groupId>
           <artifactId>jul-to-slf4j</artifactId>
           <version>1.6.1</version>
        </dependency>

        <dependency>
           <groupId>cglib</groupId>
           <artifactId>cglib</artifactId>
           <version>2.2.2</version>
        </dependency>

        <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-tx</artifactId>
           <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-webmvc</artifactId>
           <version>${org.springframework.version}</version>
        </dependency>

        <dependency>
           <groupId>org.springframework.webflow</groupId>
           <artifactId>spring-faces</artifactId>
           <version>2.3.2.RELEASE</version> <!-- no hay ${org.springframework.version} -->
        </dependency>

        <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-core</artifactId>
           <version>${org.springframework.version}</version>
        </dependency>

        <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-asm</artifactId>
           <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-context</artifactId>
           <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-expression</artifactId>
           <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-aop</artifactId>
           <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-beans</artifactId>
           <version>${org.springframework.version}</version>
        </dependency>

        <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-orm</artifactId>
           <version>${org.springframework.version}</version>
           <type>jar</type>
           <scope>compile</scope>
        </dependency>
        <dependency>
           <groupId>org.hibernate</groupId>
           <artifactId>hibernate-core</artifactId>
           <version>${org.hibernate.version}</version>
        </dependency>
        <dependency>
           <groupId>org.hibernate</groupId>
           <artifactId>hibernate-annotations</artifactId>
           <version>${org.hibernate.version}</version>
        </dependency>
        <dependency>
           <groupId>org.hibernate</groupId>
           <artifactId>hibernate-entitymanager</artifactId>
           <version>${org.hibernate.version}</version>
        </dependency>
        <dependency>
           <groupId>org.hibernate.javax.persistence</groupId>
           <artifactId>hibernate-jpa-2.0-api</artifactId>
           <version>1.0.0.Final</version>
        </dependency>
        <dependency>
           <groupId>org.slf4j</groupId>
           <artifactId>slf4j-log4j12</artifactId>
           <version>1.6.1</version>
        </dependency>
        <dependency>
           <groupId>javax.servlet</groupId>
           <artifactId>jsp-api</artifactId>
           <version>2.0</version>
           <scope>provided</scope>
        </dependency>

        <dependency>
           <groupId>javax.servlet</groupId>
           <artifactId>jstl</artifactId>
           <version>1.2</version>
        </dependency>


        <dependency>
           <groupId>aopalliance</groupId>
           <artifactId>aopalliance</artifactId>
           <version>1.0</version>
        </dependency>
        <dependency>
           <groupId>commons-logging</groupId>
           <artifactId>commons-logging</artifactId>
           <version>1.1.1</version>
        </dependency>


        <dependency>
           <!-- Hosteado con Nexus -->
           <groupId>com.oracle</groupId>
           <artifactId>ojdbc6</artifactId>
           <version>11.2</version>
           <scope>provided</scope>
        </dependency>

        <dependency>
           <!-- Hosteado con Nexus -->
           <groupId>com.microsoft.sqlserver</groupId>
           <artifactId>sqljdbc4</artifactId>
           <version>3.0</version>
           <scope>provided</scope>
        </dependency>


        <dependency>
           <groupId>javax.servlet</groupId>
           <artifactId>servlet-api</artifactId>
           <version>2.5</version>
        </dependency>
     </dependencies>
     <build>
        <plugins>
           <plugin>
              <artifactId>maven-compiler-plugin</artifactId>
              <version>2.3.2</version>
              <configuration>
                 <source>${maven.compiler.source}</source>
                 <target>${maven.compiler.target}</target>
              </configuration>
           </plugin>
        </plugins>
     </build>
  </project>
4

2 回答 2

0

test.xhtml您的复合组件的命名空间中是错误的。将其更改为:

xmlns:util="http://java.sun.com/jsf/composite/ui/util"

到:

xmlns:util="http://java.sun.com/jsf/composite/ui"
于 2013-04-02T14:50:22.443 回答
0

问题是 JSF Composite 并不像我的 CustomResource 一样,做了一个解决方法并且它现在可以工作了。可能不是最优雅的解决方案。

CustomResourceHandler.java

  import javax.faces.application.Resource;
  import javax.faces.application.ResourceHandler;
  import javax.faces.application.ResourceHandlerWrapper;
  import javax.faces.application.ResourceWrapper;
  import javax.faces.context.FacesContext;

  import com.sun.faces.util.Util;

  /**
   * Custom JSF ResourceHandler.
   * 
   * This handler bridges between Spring MVC and JSF managed resources. The handler takes
   * care of the case when a JSF facelet is used as a view by a Spring MVC Controller and the
   * view uses components like h:outputScript and h:outputStylesheet by correctly pointing the 
   * resource URLs generated to the JSF resource handler.
   * 
   * The reason this custom handler wrapper is needed is because the JSF internal logic assumes
   * that the request URL for the current page/view is a JSF url. If it is a Spring MVC request, JSF
   * will create URLs that incorrectly includes the Spring controller context.
   * 
   * This handler will strip out the Spring context for the URL and add the ".jsf" suffix, so the
   * resource request will be routed to the FacesServlet with a correct resource context (assuming the
   * faces servlet is mapped to the *.jsf pattern). 
   * 
   *
   */
  public class CustomResourceHandler extends ResourceHandlerWrapper {

      private ResourceHandler wrapped;

      public CustomResourceHandler(ResourceHandler wrapped) {
          this.wrapped = wrapped;
      }
      @Override
      public ResourceHandler getWrapped() {
          return this.wrapped;    
      }

      @Override
      public Resource createResource(String resourceName, String libraryName) {

        Resource wrapped = super.createResource(resourceName, libraryName);

           if (resourceName.endsWith(".xhtml")) {
           return wrapped;
        }
           return new CustomResource(wrapped,resourceName);
      }
      @Override
      public Resource createResource(String resourceName, String libraryName,
              String contentType) {

        Resource wrapped = super.createResource(resourceName, libraryName, contentType);

           if (resourceName.endsWith(".xhtml")) {
           return wrapped;
        }
           return new CustomResource(wrapped,resourceName);
      }

      private static class CustomResource extends ResourceWrapper {

          private Resource wrapped;
          private String resourceName;

          private CustomResource(Resource wrapped,String resourceName) {
           //super();
           this.resourceName = resourceName;
              this.wrapped = wrapped;
          }
          @Override
          public Resource getWrapped() {
              return this.wrapped;
          }
          @Override
          public String getRequestPath() {


           FacesContext context = FacesContext.getCurrentInstance();

           // si no existe el recurso lo mapeamos igualmente 
           if (this.wrapped == null) {
              return  context.getExternalContext().getRequestContextPath() + "/resources/" + resourceName;
           }

           String path = super.getRequestPath();

              String facesServletMapping = Util.getFacesMapping(context);
              // if prefix-mapped, this is a resource that is requested from a faces page
              // rendered as a view to a Spring MVC controller.
              // facesServletMapping will, in fact, be the Spring mapping
              if (Util.isPrefixMapped(facesServletMapping)) {
                  // remove the Spring mapping
                  path = path.replaceFirst("(" + facesServletMapping + ")/", "/");
                  // append .jsf to route this URL to the FacesServlet
                  path = path.replace(wrapped.getResourceName(), wrapped.getResourceName() + ".jsf");
              }
              return path;
          }

      }
  }
于 2013-04-04T14:06:47.250 回答