Spring Boot和JSF/Primefaces/Richfaces

Her*_*ick 7 jsf spring primefaces spring-boot

我已经与Spring联系了几个月,最近在浏览指南部分时遇到了Spring Boot.这些指南非常容易完成,可以很好地初步掌握项目的基本(和令人敬畏的)想法,即能够以最少的配置构建和部署企业级应用程序,同时支持各种Spring/JEE良好做法.我真的很感兴趣将Spring Boot用于测试项目,因为使用它可以更容易,更快地设置和运行,并且仍然非常接近我的生产环境.我目前正在尝试使用Spring Boot和Primefaces构建一个项目作为我选择的视图技术,但是这个设置显然不像Thymeleaf那样开箱即用,因为它在类路径中具有二进制文件足够.我尝试包含以下gradle/maven工件,但没有成功:

  • primefaces
  • JSF的API
  • JSF的IMPL
  • EL-API

Spring Boot的嵌入式Tomcat服务器启动时没有明显错误,但在尝试在浏览器中打开/ view等页面后,嵌入式服务器显示以下错误消息: HTTP Status 500 - Circular view path: would dispatch back to the current handler URL again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)

在几个不同的地方搜索后,我仍然找不到任何关于如何设置这样一个项目的资源/教程.以下是我的build.gradle文件的内容:

buildscript {
    repositories {
        maven { url "http://repo.spring.io/libs-snapshot" }
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.0.0.RC4")
    }
}

apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'spring-boot'

idea {
    module {
        downloadJavadoc = true
    }
}

group = 'com.hello'
version = '0.0.1-SNAPSHOT'

repositories {
    mavenCentral()
    mavenLocal()
    maven { url "http://repository.primefaces.org" }
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web")
//    compile ("org.thymeleaf:thymeleaf-spring4")
    compile group: 'org.primefaces', name: 'primefaces', version: '4.0'

    compile group: 'com.sun.faces', name: 'jsf-api', version: '2.2.2'
    compile group: 'com.sun.faces', name: 'jsf-impl', version: '2.2.2'
    compile group: 'javax.el', name: 'el-api', version: '1.0'
}

task wrapper(type: Wrapper) {
    gradleVersion=1.10
}
Run Code Online (Sandbox Code Playgroud)

我的主要课程:

package com.hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@EnableAutoConfiguration
@ComponentScan
@Configuration
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
Run Code Online (Sandbox Code Playgroud)

以及我对WebMvcConfigurerAdapter的实现:

package com.hello;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("view");
        registry.addViewController("/view").setViewName("view");
    }

}
Run Code Online (Sandbox Code Playgroud)

除了我的view.html文件(我也试过view.xhtml),这些是我为这个项目创建的所有文件,因为我正在尝试进行最小化设置.

如果有人能够看到我做错了什么(或者根本不做),那么非常感谢帮助.在这种情况下,我是否需要额外的文件/ bean用于JSF配置?如果是这样,在哪里以及如何放置这样的文件?

这个问题也发布在官方的Spring论坛上:http: //forum.spring.io/forum/spring-projects/boot/746552-spring-boot-and-jsf-primefaces-richfaces


编辑:在包含M. Deinum的JSF配置bean并删除WebMvcConfigurerAdapter定义(与Spring MVC相关)之后,Spring Boot似乎将请求映射到FacesServlet实例,现在我收到以下错误消息: HTTP Status 500 - Servlet.init() for servlet FacesServlet threw exception

根本原因:
java.lang.IllegalStateException: Could not find backup for factory javax.faces.context.FacesContextFactory
Run Code Online (Sandbox Code Playgroud)

新JsfConfig bean的代码:

package com.hello;

import com.sun.faces.config.ConfigureListener;
import org.springframework.boot.context.embedded.ServletListenerRegistrationBean;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

import javax.faces.webapp.FacesServlet;

@Configuration
public class JsfConfig {

    @Bean
    public FacesServlet facesServlet() {
        return new FacesServlet();
    }

    @Bean
    public ServletRegistrationBean facesServletRegistration() {
        ServletRegistrationBean registration = new ServletRegistrationBean(facesServlet(), "*.xhtml");
        registration.setName("FacesServlet");
        return registration;
    }

    @Bean
    public ServletListenerRegistrationBean<ConfigureListener> jsfConfigureListener() {
        return new ServletListenerRegistrationBean<ConfigureListener>(new ConfigureListener());
    }

    @Bean
    public ViewResolver getViewResolver(){
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/templates/");
        resolver.setSuffix(".xhtml");
        return resolver;
    }
}
Run Code Online (Sandbox Code Playgroud)

M. *_*num 6

您正在使用不能与Spring MVC一起使用的JSF,这两种技术都是不同的.您必须正确设置JSF.为此你需要添加一个FacesServlet和面ConfigureListener.这需要正确设置JSF,通常ConfigureListener会自动检测,但嵌入式版本似乎并没有这样做.

@Configuration
public class JsfConfig {

    @Bean
    public FacesServlet facesServlet() {
        return new FacesServlet();
    }

    @Bean
    public ServletRegistrationBean facesServletRegistration() {
        ServletRegistrationBean registration = new ServletRegistrationBean(facesServlet(), "*.xhtml");
        registration.setName("FacesServlet")
        return registration;
    }

    @Bean
    public ListenerRegistationBean jsfConfigureListener() {
        return new ListenerRegistrationBean(new ConfigureListener());           
    }       
}
Run Code Online (Sandbox Code Playgroud)

像这样的东西.我可能会建议您禁用DispatcherServlet等的自动配置,因为您使用的是JSF而不是Spring MVC.

@EnableAutoConfiguration(exclude={WebMvcAutoConfiguration.class,DispatcherServletAutoConfiguration }
Run Code Online (Sandbox Code Playgroud)


Her*_*ick 5

在使用Spring Boot设置FacesServlet 之后,通过louvelg 看到这个问题后我遇到了一个不同的问题,我通过在spring-web中添加了几个配置文件和一个ServletRegistrationBean来使用JSF/primefaces.web.xml和faces-config.xml文件有点伤害了Spring Boot的最小化设置,没有大量的xml文件,但这是我能用JSF找到的最小设置,如果有人知道更好/更清洁这样做的方法,请告诉我.

以下是我的gradle.build文件中的依赖项:

compile group: "org.springframework.boot", name: "spring-boot-starter"
compile group: "org.springframework", name: "spring-web", version: "4.0.2.RELEASE"

compile group: "org.apache.tomcat.embed", name: "tomcat-embed-core", version: tomcatVersion
compile group: "org.apache.tomcat.embed", name: "tomcat-embed-logging-juli", version: tomcatVersion
compile group: "org.apache.tomcat.embed", name: "tomcat-embed-jasper", version: tomcatVersion

compile group: "org.primefaces", name: "primefaces", version: "4.0"
compile group: "com.sun.faces", name: "jsf-api", version: "2.1.21"
compile group: "com.sun.faces", name: "jsf-impl", version: "2.1.21"
Run Code Online (Sandbox Code Playgroud)

在哪里tomcatVersion是"7.0.34".这里的关键变化是:

  • 删除spring-boot-starter-web,其中还包括由M. Deinum指出的Spring MVC
  • 包括spring-boot-starter(更容易启动)和spring-web
  • 明确地包括tomcat-embed依赖项,因为spring-boot-starter-web不再在这里了.

以下是我的主要课程的新内容:

package com.hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import javax.faces.webapp.FacesServlet;

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application {

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

    @Bean
    public ServletRegistrationBean servletRegistrationBean() {
        FacesServlet servlet = new FacesServlet();
        return new ServletRegistrationBean(servlet, "*.xhtml");
    }
}
Run Code Online (Sandbox Code Playgroud)

@EnableAutoConfiguration 如果您希望Spring Boot自动设置Tomcat,并且ServletRegistrationBean将xhtml请求映射到您的FacesServlet.

我的webapp目录中的WEB-INF/faces-config.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<faces-config xmlns="http://xmlns.jcp.org/xml/ns/javaee"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"
              version="2.2">
    <application>
        <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
    </application>
</faces-config>
Run Code Online (Sandbox Code Playgroud)

web.xml文件也在webapp/WEB-INF中:

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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"
           version="2.5">

    <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>*.xhtml</url-pattern>
    </servlet-mapping>
</web-app>
Run Code Online (Sandbox Code Playgroud)

servlet定义似乎是多余的,但出于某种原因,如果我从web.xml文件或servlet注册bean中删除它们,xhtml页面的呈现将无法按预期工作或根本不工作.编辑:结果是web.xml文件中没有必要进行servlet映射,这只是一个IDE问题,在我的情况下,Intellij Idea不知道servlet注册bean中定义的servlet映射,所以它在抱怨关于预期的servlet缺少映射,但应用程序运行没有问题.

感谢所有贡献者.

  • 一个小的补充:你必须将IDE的构建路径设置为src/main/webapp/WEB-INF/classes(如果你想使用IDE调试器).Eclipse默认将类放入/ bin.不幸的是,JSF不扫描此文件夹,因此它找不到任何@ManagedBean.我想你必须以类似的方式配置其他IDE. (2认同)