我正在尝试将我的 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 库? 中提到的所有内容进行操作。
对不起,我最近正在学习编程和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");