运行 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 已添加到项目方面
- 在部署程序集中添加了 Maven 依赖项
当 运行 在服务器上运行应用程序时,我没有收到任何错误,事实上我看到日志表明 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/ 前缀才能正常工作。
我有 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 已添加到项目方面
- 在部署程序集中添加了 Maven 依赖项
当 运行 在服务器上运行应用程序时,我没有收到任何错误,事实上我看到日志表明 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/ 前缀才能正常工作。