如何使用 Java 17、Spring 6、Jakarta Server Faces 4.x 和 PrimeFaces 12 检索 FacesContext?

问题描述 投票:0回答:1

我正在尝试将我的 JSF + PrimeFaces (UI) + Spring 应用程序从 Java 8 迁移到 Java 17,同时还将 Spring 版本迁移到 6。 为此,需要从 javax 库迁移到 jakarta 库。 com.sun.faces 的 jsf-api 和 jsf-impl 已删除。仅保留 org.glassfish:jakarta.faces。 是否从互联网上可用的不同来源添加了所需的库。

我遇到的问题是 FacesContext facesContext = FacesContext.getCurrentInstance();用于 @ViewScoped 的 bean 的 @PostConstruct 注解方法,并与 @Named 注解一起使用。

我收到异常,因为 facesContext 为 null,facesContext 的对象未初始化。

FacesConfig.xml

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

<faces-config xmlns="https://jakarta.ee/xml/ns/jakartaee"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-facesconfig_4_0.xsd"
              version="4.0">



    <application>

        <locale-config>
            <default-locale>en</default-locale>
            <supported-locale>en</supported-locale>
        </locale-config>
        <resource-bundle>
            <base-name>messages</base-name>
            <var>msg</var>
        </resource-bundle>

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

</faces-config>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="6.0"
         xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd">

    <display-name>controlfwk</display-name>
    <description>controlfwk</description>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath*:spring-context.xml
        </param-value>
    </context-param>

    <context-param>
        <param-name>spring.profiles.default</param-name>
        <!--<param-value>${spring.profile}</param-value>-->
        <param-value>prod</param-value>
    </context-param>

    <context-param>
        <param-name>resteasy.scan</param-name>
        <param-value>true</param-value>
    </context-param>

    <context-param>
        <param-name>resteasy.resources</param-name>
        <param-value>
            com.abc.def.cfk.web.service.rest.RestService
        </param-value>
    </context-param>

    <context-param>
        <param-name>resteasy.servlet.mapping.prefix</param-name>
        <param-value>/rest</param-value>
    </context-param>

    <context-param>
        <param-name>primefaces.FONT_AWESOME</param-name>
        <param-value>true </param-value>
    </context-param>

    <context-param>
        <param-name>primefaces.THEME</param-name>
        <param-value>smoothness</param-value>
    </context-param>

    <session-config>
        <session-timeout>360</session-timeout>
        <cookie-config>
            <path>/</path>
        </cookie-config>
    </session-config>

    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>jakarta.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>0</load-on-startup>
    </servlet>


    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <listener>
        <listener-class>
            org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
    </listener>


    <servlet>
        <servlet-name>resteasy-servlet</servlet-name>
        <servlet-class>
            org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
    </servlet>


    <servlet-mapping>
        <servlet-name>resteasy-servlet</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>home.xhtml</welcome-file>
        <welcome-file>index.htm</welcome-file>
    </welcome-file-list>

</web-app>

我尝试删除 FacesContext,如评论中所述,UI 确实提出了这一点,但这不是解决方案。

我添加了不同论坛中建议的所有 Jakarta EE jar,但没有任何区别。将 ManagedBean 替换为 Named,将 ManagedProperty 替换为带有注入注释的 ManagedProperty。

我期望获得 FacesContext 对象,例如:

FacesContext facesContext = FacesContext.getCurrentInstance();
Map<String, String> parameterMap = facesContext.getExternalContext().getRequestParameterMap();

这只是我需要 FacesContext 的一个示例。

注意:它确实适用于 Java 8、PrimeFaces 6、JSF 2.2.8-02、Spring 4.x。

编辑: 根据 BalusC 的评论,我删除了 jakarta.faces-api 并添加了 org.glassfish:jakarta.faces。

我仍然没有得到 FacesContext 对象。我按照重复链接如何通过 Maven 正确安装和配置 JSF 库? 中提到的所有内容进行操作。

spring jsf primefaces jakarta-migration
1个回答
0
投票

对不起,我最近正在学习编程和Java,所以这不是建议或解决方案,只是一个意见。这取决于您想从哪里访问 FaceContext?来自 CDI Bean 还是来自与 JSF 工具无关的类?我主要从 YouTube 视频中学习。问题是所有这些视频都基于过时的框架,而我正在尝试使用现代版本的软件做同样的事情。

我最近遇到了一个问题,我想与你的问题有关。我无法在 servlet(常规 @WebServlet)中获取 CDI Bean(@SessionScoped)作为会话属性(依次从 HTTP 请求获取),尽管这正是视频中显示的内容(确实,这不是CDI Bean,但是在那里使用的@ManagedBean(eager = true) - 已弃用)。它一直都是空的。大约一周的时间里,我试图在互联网上找到有关此问题的信息,我认为问题出在“eager”属性上(CDI有“lazy”属性,而且似乎无法更改),但我唯一能做的是我们发现(至少在现代版本的框架中),“不能保证”从与 JSF 工具无关的文件和类(例如 WebServlet)访问 Face Context。 我仍然用自己的方式解决了这种情况 - 在 CDI 构造函数中,我将 Bean 放入会话中(使用ExternalContext.getSession),并在处理请求的 servlet 中,我将 Bean 从会话中取出:

@Named(value = "searchController")
@SessionScoped
public class SearchController implements Serializable {

private SearchType searchType;
private static Map<String, SearchType> searchList = new HashMap<String, 
SearchType>(); 

 ...

public SearchController() {
    fillBooksAll();
    ResourceBundle bundle = ResourceBundle.getBundle( "nls.messages", 
            FacesContext.getCurrentInstance().getViewRoot().getLocale()
    );
    searchList.put(bundle.getString("author_name"), SearchType.AUTHOR);
    searchList.put(bundle.getString("book_name"), SearchType.TITLE);

    **((HttpSession)FacesContext.getCurrentInstance()
                    .getExternalContext().getSession(false))
                    .setAttribute("searchController", this);**    
}

在 WebServlet 中:

SearchController searchController = (SearchController) 
     request.getSession(false).getAttribute("searchController");
© www.soinside.com 2019 - 2024. All rights reserved.