【问题标题】:viewParam value not set in ViewScoped beanViewScoped bean 中未设置 viewParam 值
【发布时间】:2012-05-14 12:27:58
【问题描述】:

抱歉,可能是另一个非常基本的问题。在我的 ViewScoped bean 中,'viewParam' 看起来已经设置好了,但是当我开始使用它时,它的值为 null。我在设置器 (setEventId()) 中放置了一个断点,它获取了值,但是在我的 preRenderView 指定的方法中,它消失了,所以我无法加载我试图检索的事件对象。

当我的 bean 是 RequestScoped 时,这工作正常,但我发现在 POST 和随后的验证错误中,我的所有详细信息都丢失了,并且读到 ViewScoped 是解决这个问题的方法。

我已升级到 Mojarra 2.1.7,因为我认为这可能是一个错误,并且确实在他们的 JIRA 中列出了一个“严重错误”,已在 2.1.7 中修复,但我在 Glassfish 日志中验证它是使用较新的版本,我仍然遇到同样的问题:http://java.net/jira/browse/JAVASERVERFACES-2266

请帮忙,这是我的 bean(我尝试过使用和不使用 'ManagedProperty' 注释)

@ViewScoped
@Named
public class EventController extends AbstractController {

    private static final Logger logger = Logger.getLogger("EventController");

    /**
     * Request param managed property
     */
    @ManagedProperty(value="#{param.eventId}")
    private Long eventId;                

    private Event event = new Event();

    /**
     * The event dao
     */
    @Inject
    private EventDao eventDao;    

    /**
     * Load the event (requires eventId has a value)
     * @return 
     */
    public void loadEvent() {
        event = eventDao.find(eventId);
    }    

    /**
     * @return the eventId
     */
    public Long getEventId() {
        return eventId;
    }

    /**
     * @param eventId the eventId to set
     */
    public void setEventId(Long eventId) {
        this.eventId = eventId;
    }   
}

这是我在“listEvents”页面中构建链接的方式

<h:link value="Full details" outcome="/calendar/viewEvent" includeViewParams="true">
<f:param name="eventId" value="#{calendarController.event.eventId}" />
</h:link>

这里是需要 eventId 属性的页面

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:c="http://java.sun.com/jsp/jstl/core">

    <body>

        <ui:composition template="/WEB-INF/templates/standardTemplate.xhtml">

    <f:metadata>
        <f:viewParam name="eventId" value="#{eventController.eventId}"/>
        <f:event type="preRenderView" listener="#{eventController.loadEvent}" />
    </f:metadata>            

            <ui:define name="content">      

                <h1>Event details for: #{eventController.event.title}</h1>
                <h:form>
                    <p:messages/>                                               

                    <p:panelGrid style="margin-top:20px">  
                        <f:facet name="header">  
                            <p:row>  
                                <p:column colspan="4">Event details</p:column>  
                            </p:row>  
                        </f:facet>  

                        <p:row>  
                            <p:column>
                                Title
                            </p:column>  
                            <p:column colspan="3">
                                <p:inputText value="#{eventController.event.title}" size="49"/>
                                <h:inputHidden id="eventId" value="#{eventController.event.eventId}"/>
                            </p:column>   
                        </p:row>                                                                                                   
                </h:form>                                
            </ui:define>
        </ui:composition>            
    </body>
</html>

【问题讨论】:

    标签: java jsf jsf-2


    【解决方案1】:

    您是通过 CDI 而不是 JSF 管理 bean。 JSF @ViewScoped 注释仅适用于 JSF @ManagedBean,不适用于 CDI @Named。在 CDI @Named 上,您只能使用 CDI 范围,而不是 JSF 范围。 CDI 提供的最接近的是@ConversationScoped。但是您必须使用一些额外的样板代码自己管理对话的开始和结束。

    同样的故事也适用于 JSF @ManagedProperty 注释。它仅适用于 JSF @ManagedBean,不适用于 CDI @Named。对于 CDI,您应该使用 @Injectcustom HTTP param annotation

    JSF 问题 2266 与这一切无关

    【讨论】:

    • 啊。谢谢,我用这个把头发扯掉了。将 Named 替换为 ManagedBean 并删除 ManagedProperty 注释。现在运行良好,并在我收到验证错误时记住这些值。
    • 不客气。请注意,您仍然可以在 @ManagedBean 中使用 @Inject。或者只是@EJB,如果它是需要在容器管理的事务上下文中运行并且你的容器支持它的服务(Glassfish、JBoss AS、TomEE 等)。
    【解决方案2】:

    我遇到了一个非常相似(如果不确切的话)的问题。 我在 Glassfish 4.0 build 89 和 Primefaces 4.0 上使用 Java EE 7。 Glassfish 报告说它正在使用 Mojarra 2.2.0。 我使用的是 CDI 类型注释,即 @Named 和 @javax.faces.view.Viewscoped。 我的 *.xhtml 文件是这样开始的

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml"
        xmlns:h="http://xmlns.jcp.org/jsf/html"
        xmlns:f="http://xmlns.jcp.org/jsf/core"
        xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
        xmlns:p="http://primefaces.org/ui">
    
    <f:metadata>
        <f:viewAction action="#{personController.initialise}" />
        <f:viewParam name="id" value="#{personController.id}" />
    </f:metadata>
    ...
    

    无论我尝试了什么,它都没有设置我的视图参数。 我读到 Mojarra 2.2.1 存在问题,并认为 Mojarra 2.2.0 可能相同。 Updatetool 并没有比我所拥有的更进一步更新 Mojarra,所以我手动进行了更新。 我将来自http://repo1.maven.org/maven2/org/glassfish/javax.faces/2.2.5/ 的最新 Mojarra 实现的副本放入 $GLASSFISH_HOME/glassfish/modules 目录,将其重命名为 javax.faces.jar 并备份现有的 javax.faces.jar 文件。 重新启动 Glassfish 并报告它现在正在使用 Mojarra 2.2.5。问题消失了,代码运行良好。

    【讨论】:

      猜你喜欢
      • 2012-05-02
      • 1970-01-01
      • 1970-01-01
      • 2013-10-10
      • 2016-12-26
      • 1970-01-01
      • 2011-04-20
      • 1970-01-01
      相关资源
      最近更新 更多