运行 Spring 在 Eclipse Tomcat 上启动应用程序时不呈现 JSF 组件

JSF components are not rendered when running Spring Boot app on Eclipse Tomcat

我有 Spring 引导 JSF 应用程序,运行在嵌入式 Tomcat 上没问题 但是当在 Eclipse Tomcat 上尝试 运行 时,jsf 组件没有被渲染,这是我的 pom 文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <modelVersion>4.0.0</modelVersion> 

    <groupId>org.springframework</groupId>
    <artifactId>gs-accessing-data-jpa</artifactId>  
    <version>0.1.0</version>

    <parent>
        <groupId>org.springframework.boot</groupId> 
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.4.RELEASE</version>
    </parent>

    <packaging>war</packaging>


    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>


        <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>    

        <dependency>
            <groupId>com.sun.faces</groupId>
            <artifactId>jsf-api</artifactId>
            <version>2.2.14</version>
        </dependency>

        <dependency>
            <groupId>com.sun.faces</groupId>
            <artifactId>jsf-impl</artifactId>
            <version>2.2.14</version>
        </dependency>

        <dependency>
            <groupId>org.primefaces</groupId>
            <artifactId>primefaces</artifactId>
            <version>6.0</version>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>


        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <scope>provided</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <!--  
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            -->
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-releases</id>
            <name>Spring Releases</name>
            <url>https://repo.spring.io/libs-release</url>
        </repository>
        <repository>
            <id>org.jboss.repository.releases</id>
            <name>JBoss Maven Release Repository</name>
            <url>https://repository.jboss.org/nexus/content/repositories/releases</url>
        </repository>
    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>spring-releases</id>
            <name>Spring Releases</name>
            <url>https://repo.spring.io/libs-release</url>
        </pluginRepository>
    </pluginRepositories>

</project>

主要class:

package hello;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import javax.faces.application.ProjectStage;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.HandlesTypes;

import org.apache.catalina.Context;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.CustomScopeConfigurer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.tomcat.TomcatContextCustomizer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;

import com.sun.faces.config.FacesInitializer;

@SpringBootApplication
public class Application extends SpringBootServletInitializer {

    private static final Logger log = LoggerFactory.getLogger(Application.class);

    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }

    @Bean
    public ServletContextInitializer servletContextCustomizer() {
        return new ServletContextInitializer() {
            @Override
            public void onStartup(ServletContext sc) throws ServletException {
                sc.setInitParameter(ProjectStage.PROJECT_STAGE_PARAM_NAME, ProjectStage.Development.name());
            }
        };
    }

    @Bean
    public static CustomScopeConfigurer customScopeConfigurer() {
        CustomScopeConfigurer configurer = new CustomScopeConfigurer();
        configurer.setScopes(Collections.<String, Object>singletonMap(FacesViewScope.NAME, new FacesViewScope()));
        return configurer;
    }

    @Bean
    public EmbeddedServletContainerFactory embeddedServletContainerFactory() {
        TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();

        tomcat.addContextCustomizers(new TomcatContextCustomizer() {
            @Override
            public void customize(Context context) {
                context.addServletContainerInitializer(new FacesInitializer(),
                        getServletContainerInitializerHandlesTypes(FacesInitializer.class));
                context.addWelcomeFile("index.xhtml");
                context.addMimeMapping("eot", "application/vnd.ms-fontobject");
                context.addMimeMapping("ttf", "application/x-font-ttf");
                context.addMimeMapping("woff", "application/x-font-woff");
            }
        });

        return tomcat;
    }

    @SuppressWarnings("rawtypes")
    private Set<Class<?>> getServletContainerInitializerHandlesTypes(
            Class<? extends ServletContainerInitializer> sciClass) {
        HandlesTypes annotation = sciClass.getAnnotation(HandlesTypes.class);
        if (annotation == null) {
            return Collections.emptySet();
        }

        Class[] classesArray = annotation.value();
        Set<Class<?>> classesSet = new HashSet<Class<?>>(classesArray.length);
        for (Class clazz : classesArray) {
            classesSet.add(clazz);
        }

        return classesSet;
    }

}

其他配置:

当 运行 在服务器上运行应用程序时,我没有收到任何错误,事实上我看到日志表明 JSF 已成功启动:

2017-01-28 16:04:47.145  INFO 6880 --- [ost-startStop-1] hello.Application                        : Started Application in 13.522 seconds (JVM running for 19.312)
2017-01-28 16:04:47.231  INFO 6880 --- [ost-startStop-1] j.e.resource.webcontainer.jsf.config     : Initializing Mojarra 2.2.14 ( 20161114-2153 unable to get svn info) for context '/spring-hibernate-jsf-web'
2017-01-28 16:04:47.539  INFO 6880 --- [ost-startStop-1] j.e.r.webcontainer.jsf.application       : JSF1048: PostConstruct/PreDestroy annotations present.  ManagedBeans methods marked with these annotations will have said annotations processed.
2017-01-28 16:04:48.557  INFO 6880 --- [ost-startStop-1] j.e.resource.webcontainer.jsf.config     : Monitoring file:/C:/Users/lenovo/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/spring-hibernate-jsf-web/WEB-INF/faces-config.xml for modifications
2017-01-28 16:04:48.630  INFO 6880 --- [ost-startStop-1] .w.PostConstructApplicationEventListener : Running on PrimeFaces 6.0
2017-01-28 16:04:48.790  INFO 6880 --- [           main] org.apache.coyote.ajp.AjpNioProtocol     : Starting ProtocolHandler [ajp-nio-8009]
2017-01-28 16:04:48.799  INFO 6880 --- [           main] org.apache.catalina.startup.Catalina     : Server startup in 20021 ms
2017-01-28 16:04:49.463  INFO 6880 --- [nio-8080-exec-2] .a.c.c.C.[.[.[/spring-hibernate-jsf-web] : Initializing Spring FrameworkServlet 'dispatcherServlet'
2017-01-28 16:04:49.463  INFO 6880 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
2017-01-28 16:04:49.511  INFO 6880 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 47 ms

访问 xhtml 页面时没有错误,但 jsf 和 Primefaces 组件未呈现。我该如何解决这个问题?

我发现了这个问题,这很奇怪,而 运行 嵌入的 jar tomcat 我能够在没有 /faces/ 前缀的情况下访问 xhtml 页面,但在 eclipse tomcat我必须在 xhtml 页面之前添加 /faces/ 前缀才能正常工作。