首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Spring 2.7.1与JSF2.2 (Mojarra)和Primefaces 6.2.9集成

Spring 2.7.1与JSF2.2 (Mojarra)和Primefaces 6.2.9集成
EN

Stack Overflow用户
提问于 2022-06-30 07:09:41
回答 1查看 576关注 0票数 1

我已经用下面的堆栈设置了工作-

Spring 5

JSF Mojarra 2.2.14

原面6.2.9

  • 这个应用程序是作为WAR构建的。
  • 有配置FacesServlet以服务*.xhtml请求的web.xml。JSF和Primefaces的所有init参数都定义为web.xml中的上下文params,
  • 也有faces-带有SpringBeanFacesELResolver的config.xml用于所有JSF托管Beans以及@ManagedProperty和JSF作用域。托管bean使用@managedproperty获取对Spring的引用,并进行服务调用以填充JSF类中显示的数据。pages.
  • @ManagedBean类还使用@PostConstructforinitialization.

这在weblogic应用服务器和tomcat中都运行得很好。

我们正在尝试使用最新的2.7.1版本将其转换为Spring引导项目。作为这个的一部分

  • web.xml已被java配置类替换,如下所示-

代码语言:javascript
运行
复制
@SpringBootApplication(scanBasePackages = {"com.demo.spring.boot.jsfprimefaces","com.xxx.eee"})
@ImportResource({"classpath:spring-root-config.xml","classpath:spring-security-config.xml","classpath:spring-restclient-config.xml"})
public class JsfPrimefacesApplication implements ServletContextInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        servletContext.setInitParameter("com.sun.faces.forceLoadConfiguration", Boolean.TRUE.toString()); 
        // Set JSF/Primefaces init params
        servletContext.setInitParameter("javax.faces.DEFAULT_SUFFIX", ".xhtml");
        servletContext.setInitParameter("javax.faces.STATE_SAVING_METHOD", "client");
        servletContext.setInitParameter("javax.faces.PROJECT_STAGE", "Production");
        servletContext.setInitParameter("javax.faces.VALIDATE_EMPTY_FIELDS", "false");
        servletContext.setInitParameter("javax.faces.FACELETS_SKIP_COMMENTS", "true");
        //servletContext.setInitParameter("javax.faces.CONFIG_FILES", "/WEB-INF/faces-config.xml");
        servletContext.setInitParameter("javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE", "true");

        servletContext.setInitParameter("primefaces.THEME", "aristo");
        servletContext.setInitParameter("primefaces.PUBLIC_CAPTCHA_KEY", "DDDDD");
        servletContext.setInitParameter("primefaces.PRIVATE_CAPTCHA_KEY", "EEEEE");
        servletContext.setInitParameter("primefaces.UPLOADER", "commons");

        FacesInitializer facesInitializer = new FacesInitializer();
        facesInitializer.onStartup(null, servletContext);

    }

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

}

很少有其他@配置类-

代码语言:javascript
运行
复制
@Configuration
public class PortalFilterConfiguration {

    @Bean
    public FilterRegistrationBean<RewriteFilter> rewriteFilter() {
        FilterRegistrationBean<RewriteFilter> rwFilter = new FilterRegistrationBean<RewriteFilter>(new RewriteFilter());
        rwFilter.setDispatcherTypes(
                EnumSet.of(DispatcherType.FORWARD, DispatcherType.REQUEST, DispatcherType.ASYNC, DispatcherType.ERROR));
        rwFilter.addUrlPatterns("/*");
        return rwFilter;
    }
}
代码语言:javascript
运行
复制
@Configuration
public class PortalListenerConfiguration {

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

    static class JsfApplicationObjectConfigureListener extends ConfigureListener {

        @Override
        public void contextInitialized(ServletContextEvent sce) {
            super.contextInitialized(sce);

            ApplicationFactory factory = (ApplicationFactory) FactoryFinder
                    .getFactory(FactoryFinder.APPLICATION_FACTORY);
            Application app = factory.getApplication();

            app.addELResolver(new SpringBeanFacesELResolver());
        }
    }

}
代码语言:javascript
运行
复制
@Configuration
public class PortalServletConfiguration {

    @Bean
    public ServletRegistrationBean<FacesServlet> jsfServletRegistration(ServletContext servletContext) {
        ServletRegistrationBean<FacesServlet> srb = new ServletRegistrationBean<FacesServlet>();
        srb.setServlet(new FacesServlet());
        srb.setUrlMappings(Arrays.asList("*.xhtml"));
        srb.setLoadOnStartup(1);
        return srb;
    }
}

以下是pom.xml内容-

代码语言:javascript
运行
复制
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.1</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.demo.spring.boot</groupId>
    <artifactId>jsf-primefaces</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>jsf-primefaces</name>
    <description>Demo project for Spring Boot JSF Primefaces</description>
    <packaging>war</packaging>
    <repositories>
        <repository>
            <id>no-commons-logging</id>
            <name>No-commons-logging Maven Repository</name>
            <layout>default</layout>
            <url>http://repository.jboss.org/</url>
        </repository>
        <repository>
            <id>prime-repo</id>
            <name>Prime Repo</name>
            <url>http://repository.primefaces.org</url>
        </repository>
        <repository>
            <id>localrepository</id>
            <url>file://../3rd-Party-Dependencies</url>
        </repository>
    </repositories>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-ldap</artifactId>
        </dependency>
        <dependency>
            <groupId>com.oracle.database.jdbc</groupId>
            <artifactId>ojdbc8</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!-- JSF Libraries -->
        <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>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>
        <!-- Primefaces & its dependent jars -->
        <dependency>
            <groupId>org.primefaces</groupId>
            <artifactId>primefaces</artifactId>
            <version>6.2.9</version>
        </dependency>

        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
        </dependency>
        <dependency>
            <groupId>org.ocpsoft.rewrite</groupId>
            <artifactId>rewrite-servlet</artifactId>
            <version>3.4.1.Final</version>
        </dependency>
        <dependency>
            <groupId>org.ocpsoft.rewrite</groupId>
            <artifactId>rewrite-config-prettyfaces</artifactId>
            <version>3.4.1.Final</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>18.0</version>
        </dependency>   
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
        <dependency>
                <groupId>net.sf.opencsv</groupId>
                <artifactId>opencsv</artifactId>
                <version>2.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox</artifactId>
            <version>2.0.24</version>
        </dependency>           
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <outputDirectory>src/main/webapp/WEB-INF/classes</outputDirectory>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

faces-config.xml放在src/main/webapp/webapp下面。以下内容-

代码语言:javascript
运行
复制
<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 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>
<locale-config>.....
<resource-bundle>.....
 </application>
</faces-config>

问题

应用程序正在启动。但是,似乎没有一个JSF托管bean被初始化,因为我根本没有看到@PostContruct方法被调用。使用托管bean名称的所有EL引用(如#{} )都失败,错误如下

代码语言:javascript
运行
复制
javax.faces.view.facelets.TagAttributeException Attribute did not evaluate to a String or Locale: null

当我在@ManagedBean之上添加@Component到一个JSF托管bean时,这会导致@PostConstruct被调用,这可能意味着在我们以前的设置中,@ManagedBean类是由JSF加载的,但是在这个新的设置中,它们被忽略了。

有谁能帮我建议一下需要做些什么才能让它发挥作用?

问候

雅各布

更新1

根据注释修改配置类如下-

代码语言:javascript
运行
复制
@SpringBootApplication(scanBasePackages = { "com.demo.spring.boot.jsfprimefaces", "com.ddd.efulfillment" })
@ImportResource({ "classpath:spring-root-config.xml", "classpath:spring-security-config.xml",
        "classpath:spring-restclient-config.xml" })
public class JsfPrimefacesApplication extends SpringBootServletInitializer {

    @Bean
    public ServletContextInitializer servletContextInitializer() {
        return servletContext -> {
            //servletContext.addListener(com.sun.faces.config.ConfigureListener.class);
            servletContext.setInitParameter("com.sun.faces.forceLoadConfiguration", Boolean.TRUE.toString());
            // Set JSF/Primefaces init params
            servletContext.setInitParameter("javax.faces.DEFAULT_SUFFIX", ".xhtml");
            servletContext.setInitParameter("javax.faces.STATE_SAVING_METHOD", "client");
            servletContext.setInitParameter("javax.faces.PROJECT_STAGE", "Production");
            servletContext.setInitParameter("javax.faces.VALIDATE_EMPTY_FIELDS", "false");
            servletContext.setInitParameter("javax.faces.FACELETS_SKIP_COMMENTS", "true");
            // servletContext.setInitParameter("javax.faces.CONFIG_FILES",
            // "/WEB-INF/faces-config.xml");
            servletContext.setInitParameter("javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE",
                    "true");

            servletContext.setInitParameter("primefaces.THEME", "aristo");
            servletContext.setInitParameter("primefaces.PUBLIC_CAPTCHA_KEY",
                    "ddd");
            servletContext.setInitParameter("primefaces.PRIVATE_CAPTCHA_KEY",
                    "ssss");
            servletContext.setInitParameter("primefaces.UPLOADER", "commons");
            FacesInitializer facesInitializer = new FacesInitializer();
            facesInitializer.onStartup(null, servletContext);

        };
    }

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

但同样的问题仍然存在。

在调试时,似乎托管bean在类com.sun.faces.config.processor.ManagedBeanConfigProcessor中通过方法"processAnnotations(ManagedBean.class);“进行标识。它有类似于下面的代码

代码语言:javascript
运行
复制
 FacesContext ctx = FacesContext.getCurrentInstance();
        ApplicationAssociate associate =
              ApplicationAssociate.getInstance(ctx.getExternalContext());
        AnnotationManager manager = associate.getAnnotationManager();
        manager.applyConfigAnnotations(ctx,
                                      annotationType,
                                      ConfigManager.getAnnotatedClasses(ctx).get(annotationType));

我认为@ManagedBean注释类的映射是NULL。不知道为什么。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-12 06:49:04

JSF2.2注释只有在具有这些注释的类显式提供给FacesInitializer之后才被识别,如下所示-

代码语言:javascript
运行
复制
facesInitializer.onStartup(loadJSFAnnotatedClasses(package1...packageN),servletContext);

import com.google.common.collect.ImmutableMap;
import com.google.common.reflect.ClassPath;

private Set<Class<?>> loadJSFAnnotatedClasses(String... packageNames) {
        Set<Class<?>> annotatedClasses = new HashSet<Class<?>>();
        try {
            for (String packageName : packageNames) {
                annotatedClasses.addAll(ClassPath.from(ClassLoader.getSystemClassLoader()).getAllClasses().stream()
                        .filter(clazz -> clazz.getPackageName().equalsIgnoreCase(packageName))
                        .map(clazz -> clazz.load()).collect(Collectors.toSet()));
            }
        } catch (Exception e) {
            return annotatedClasses;
        }

        return annotatedClasses;
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72811623

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档