【问题标题】:Why is JSF in GlassFish 5.1.0 setting the ID property of my @ViewScoped CDI bean to null?为什么 GlassFish 5.1.0 中的 JSF 将我的 @ViewScoped CDI bean 的 ID 属性设置为 null?
【发布时间】:2019-04-23 20:46:43
【问题描述】:

我正在从 GlassFish 4.1.2 升级到 GlassFish 5.1.0,遇到了一个问题,即 JSF 生命周期的更新模型阶段将我的 @ViewScoped CDI 支持 bean 的 ID 属性的值设置为 null .以下是我的简化视图。

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui"
template="/WEB-INF/templates/modena.xhtml">
<ui:define name="title">Location Editor2</ui:define>
<ui:define name="content">
    <f:metadata>
        <f:viewParam name="id" value="#{locationEditor2.location.id}" />
        <f:viewAction action="#{locationEditor2.setLocationById}" />
    </f:metadata>
    <h:form id="location-editor-form">
        <p:commandButton value="Update" styleClass="RaisedButton"
            action="#{locationEditor2.updateLocation}" update="@form" />
    </h:form>
</ui:define>
</ui:composition>

以下是我的简化 CDI 支持 bean。

import java.io.Serializable;

import javax.ejb.EJB;
import javax.ejb.EJBException;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Named;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.elliottlogic.elis.ejb.location.Location;
import com.elliottlogic.elis.ejb.location.LocationManager;
import com.elliottlogic.elis.ejb.security.AuthorizationException;
import com.elliottlogic.elis.wa.core.ExceptionTools;

/**
 * The <code>LocationEditor2</code> class TODO Complete Type Description
 *
 * @author jre
 * @version $Id: $
 *
 */
@Named
@ViewScoped
public class LocationEditor2 implements Serializable {

final static Logger logger = LoggerFactory.getLogger(LocationEditor2.class.getName());

static final long serialVersionUID = 1L;

private Location location = new Location();

@EJB
private LocationManager locationManager;

/**
 * Configures model using persisted values.
 * 
 * @throws AuthorizationException
 */
public void setLocationById() throws AuthorizationException {

    try {

        location = locationManager.readLocationByID(location.getId());

    } catch (EJBException e) {

        FacesContext.getCurrentInstance().addMessage(null,
                new FacesMessage(FacesMessage.SEVERITY_ERROR, "Location not found.", "Location not found."));

        ExceptionTools.unwrapEJBException(FacesContext.getCurrentInstance(), e);

    }

}

/**
 * Saves the changes to the location.
 * 
 * @return
 */
public String updateLocation() {

    logger.debug("Location ID: {}", location.getId());

    return null;

}

/**
 * @return the location
 */
public Location getLocation() {
    return location;
}

/**
 * @param location
 *            the location to set
 */
public void setLocation(Location location) {
    this.location = location;
}

}

以下演示了该问题:

  1. Lo​​cationEditor2.xhtml?id=1 上的点浏览器
  2. 选择[更新]按钮。
  3. updateLocation 方法记录“位置 ID:1”
  4. 选择[更新]按钮
  5. updateLocation 方法记录“Location ID: null”

我验证了视图没有被重新创建,并且在更新模型 JSF 阶段有东西正在调用 setId(Long id) 方法,其值为 null。

为什么 JSF 更新模型阶段在第二次和另外的回发期间将我的实体 ID 设置为空?

【问题讨论】:

  • 我正在使用 LifeCycleListener 来分析时刻的 JSF 阶段。
  • 使用 LifeCycleListener,我看到在更新模型阶段调用了 setId 方法。在成功的情况下,现有的ID和新的ID是相同的,而在不成功的情况下,现有的ID是正确的,而新的ID是空的。我没有以表格形式发送 ID,所以我不明白 JSF 为什么要更改它。
  • 我假设您在抱怨我的示例代码。我正在从头开始构建一个简化的客户端,以了解 GlassFish 在 4.1.2 和 5.1.0 版本之间发生了什么变化以破坏我的代码,并在完成后更新上述代码。
  • 我按照@Kukeltje 的要求通过简化代码来编辑原始帖子。
  • 嗨 tgabksor 尝试。但这不是关于“简化”,而是关于minimal reproducible example。另见stackoverflow.com/tags/jsf/info

标签: jsf glassfish


【解决方案1】:

问题的根本原因是在 JSF 生命周期的更新模型阶段调用我的实体上的 setId(null) 方法。我在 setId() 方法中使用 StackTraceElement[] 数组来查看调用方法,并确定 UIViewParameter 类的 updateModel 方法是罪魁祸首。

经过一番谷歌搜索,我找到了OmniFaces viewParam Showcase,它提供了“无状态模式,以避免在回发时进行不必要的转换、验证和模型更新”。在更改我的代码以使用 OmniFaces viewParam 组件后,JSF 更新模型基础架构在回发期间停止在我的实体上调用 setId() 方法,并且一切都像在 GlassFish 4.1.2 中一样工作。

解决方案是从标准 f:viewParam 迁移到 OmniFaces o:viewParam。

【讨论】:

猜你喜欢
  • 2015-04-15
  • 1970-01-01
  • 2013-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-28
  • 1970-01-01
相关资源
最近更新 更多