1

我对我的 JSF2/richfaces 4 项目产生了奇怪的影响。我使用 viewscoped bean 和 datascroller 来查看来自我的支持 bean 的一些数据。bean 是 viewscoped 并传递figureId参数我触发preRenderView事件。

<f:metadata>
    <f:viewParam name="figureId" value="#{pointEdit.figureId}" >
        <f:convertNumber pattern="###" />
    </f:viewParam>
    <f:event type="preRenderView" listener="#{pointEdit.init}" />
</f:metadata>

显示正常,但是当我单击 datascroller 的第二个站点时,我得到此行的 nullponter 异常:<f:event type="preRenderView" listener="#{pointEdit.init}" />.

javax.el.ELException: /pointEdit.xhtml @17,66 listener="#{pointEdit.init}": java.lang.NullPointerException
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:111)
    at com.sun.faces.facelets.tag.jsf.core.DeclarativeSystemEventListener.processEvent(EventHandler.java:128)
    at javax.faces.component.UIComponent$ComponentSystemEventListenerAdapter.processEvent(UIComponent.java:2477)
    at javax.faces.event.SystemEvent.processListener(SystemEvent.java:106)
    at com.sun.faces.application.ApplicationImpl.processListeners(ApplicationImpl.java:2102)
    at .....
Caused by: java.lang.NullPointerException
    at com.ebcont.gtv.ePrometheus.web.backingbean.PointEdit.init(PointEdit.java:74)  // <--first access to figure
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.el.parser.AstValue.invoke(AstValue.java:262)
    at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278)
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
    ... 27 more

我的豆子:

@ManagedBean
@ViewScoped
public class PointEdit implements Serializable {

    public void init() {
        FigureService figureService = Utils.getSpringBean(FigureService.class);
        figure = figureService .getById(figureId); // figureId will NOT be passed from GET
        pointListToDisplay = figure.getPoints();   // nullpointer :-(

在我导入新数据之前,它在我的测试数据上运行良好。为什么我的 figureId GET 参数在 init 函数中找不到?使用我的测试数据(5 位数)我从来没有遇到过这个问题。

更新:

<!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://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:a4j="http://richfaces.org/a4j"
    xmlns:rich="http://richfaces.org/rich"
    xmlns:c="http://java.sun.com/jsp/jstl/core">

<body>
    <h:messages errorStyle="color:red" warnStyle="color:yellow" />
    <rich:tabPanel switchType="client">
        <rich:tab header="Punkte">
            <rich:panel>
                <f:facet name="header">
                    #{msg.pointEditDetail_figure_header }
                </f:facet>
                <div style="position: relative;">
                    <h:graphicImage url="/image?figureid=#{pointEdit.figure.id}"
                        style="border: solid 2px #013476;z-index: -2;">

                        <a4j:repeat value="#{pointEdit.points}" var="thepoi">
                            <h:panelGroup layout="block"
                                style="margin-top: -27px;top:#{thepoi.y}px; left: #{thepoi.x}px; background-image: url('images/poipin.png');background-repeat:none;width: 25px; height:27px; position:absolute; z-index: -0.9;display:none;"
                                styleClass="poi #{thepoi.id }">
                                <div style="margin-top: 27px;">
                                    <a4j:repeat value="#{thepoi.labels}" var="poilabel">
                                        <h:panelGroup layout="block"
                                            styleClass="poilabel label#{thepoi.id}" style="display:none;">
                                            <div style="color: white; z-index: 1; position: relative;">
                                                <h:outputText value="#{poilabel.locale.isoCode}:"
                                                    style="background-image: url('images/layerbackground.png'); background-repeat: both;" />
                                                <h:outputText value="#{poilabel.label.labelText}"
                                                    style="background-image: url('images/layerbackground.png'); background-repeat: both;"
                                                    rendered="#{not empty poilabel.label.labelText}" />
                                                <h:outputText value="Nicht verfügbar"
                                                    style="background-image: url('images/layerbackground.png'); background-repeat: both;"
                                                    rendered="#{empty poilabel.label.labelText }" />
                                            </div>
                                        </h:panelGroup>
                                    </a4j:repeat>
                                </div>
                            </h:panelGroup>
                        </a4j:repeat>
                    </h:graphicImage>
                </div>
                <br/>
                <h:commandButton value="#{msg.pointEditDetail_show_all_button}" 
                    onclick="$('.poi').toggle()"
                    rendered="#{ not empty pointEdit.points}" />

                <h:button outcome="viewer.xhtml" value="#{msg.pointEditDetail_button_viewer}">
                    <f:param name="figureId" value="#{pointEdit.figure.id}"/>
                    <f:param name="zoom" value="1"/>
                </h:button>
            </rich:panel>
            <br />

            <rich:panel>
                <f:facet name="header">
                    #{msg.pointEditDetail_points_header }
                </f:facet>
                <h:form>
                    <rich:dataTable value="#{pointEdit.points}" var="point"
                        id="pointtable" rows="10" rowKeyVar="rowId">

                        <rich:column>
                            <f:facet name="header">
                                #{msg.pointEditDetail_table_header_rowkey}
                            </f:facet>
                            #{rowId+1}
                        </rich:column>
                        <rich:column sortBy="#{point.id}" id="id"
                            sortOrder="#{pointEdit.pointIdOrder}">
                            <f:facet name="header">
                                <a4j:commandLink
                                    value="#{msg.pointEditDetail_table_header_point} #{msg.pointEditDetail_table_header_id }"
                                    render="pointtable" action="#{pointEdit.sortByPointId}" />
                            </f:facet>
                            #{point.id}
                        </rich:column>
                        <rich:column>
                            <f:facet name="header">
                                #{msg.pointEditDetail_table_header_x}
                            </f:facet>
                            #{point.x }
                        </rich:column>
                        <rich:column>
                            <f:facet name="header">
                                #{msg.pointEditDetail_table_header_y}
                            </f:facet>
                            #{point.y }
                        </rich:column>
                        <!-- filter (Object that extends Filter<?>), filterMethod, filterExpression -->
                        <rich:column filter="#{pointEdit.labelFilter}">
                            <f:facet name="header">
                                #{msg.pointEditDetail_table_header_label}

                                <h:inputText value="#{pointEdit.labelFilterText}">
                                    <a4j:ajax event="change" render="pointtable" execute="@this" requestDelay="700"
                                        ignoreDupResponses="true"/>
                                </h:inputText>
                            </f:facet>
                            <a4j:repeat var="pointlabel" value="#{point.labels}">
                                #{pointlabel.locale.isoCode}:
                                <h:outputText value="#{pointlabel.label.labelText}"
                                    rendered="#{not empty pointlabel.label}" />
                                <h:outputText value="#{msg.pointEditDetail_not_available}"
                                    rendered="#{empty pointlabel.label}" />
                                <br />
                            </a4j:repeat>
                        </rich:column>
                        <rich:column style="text-align:center">
                            <f:facet name="header">
                                #{msg.pointEditDetail_table_header_show_point}
                            </f:facet>
                            <h:selectBooleanCheckbox styleClass="pinchk#{point.id}"
                                value="false"
                                onchange="checkboxdrivendisplay(this,'.#{point.id }');checkboxdrivendisplay(this,'.lblchk#{point.id }');"
                                onmouseover="jQuery('.#{point.id }').show(); jQuery('.lblchk#{point.id }').show();"
                                onmouseout="checkboxdrivendisplay(this,'.#{point.id }');checkboxdrivendisplay(this,'.lblchk#{point.id }');">

                            </h:selectBooleanCheckbox>
                        </rich:column>
                        <rich:column style="text-align:center;">
                            <f:facet name="header">
                                #{msg.pointEditDetail_table_header_show_label}
                            </f:facet>
                            <h:selectBooleanCheckbox style="display:none"
                                styleClass="lblchk#{point.id}" value="false"
                                onclick="checkboxdrivendisplay(this,'.label#{point.id }');"
                                onmouseover="jQuery('.label#{point.id}').show();"
                                onmouseout="checkboxdrivendisplay(this,'.label#{point.id }');">
                            </h:selectBooleanCheckbox>
                        </rich:column>
                        <rich:column>
                            <f:facet name="header">
                                #{msg.pointEditDetail_table_header_edit_label }
                            </f:facet>
                            <center>
                                <h:link outcome="labelEdit.xhtml" value="#{msg.pointEditDetail_table_edit_label}">
                                    <f:param name="pointId" value="#{point.id}"/>
                                </h:link>
                            </center>
                        </rich:column>
                        <rich:column>
                            <f:facet name="header">
                                #{msg.pointEditDetail_table_header_tag }
                            </f:facet>
                            <a4j:repeat var="tag" value="#{point.tags}" varStatus="index">
                                <h:link outcome="search.xhtml" value="#{tag.tag}">
                                    <f:param name="tags" value="true" />
                                    <f:param name="labels" value="false" />
                                    <f:param name="legends" value="false" />
                                    <f:param name="query" value="#{tag.tag}" />
                                </h:link> &nbsp;
                            </a4j:repeat>
                        </rich:column>
                        <rich:column>
                            <f:facet name="header">
                                #{msg.pointEditDetail_table_header_edit_tag }
                            </f:facet>
                            <center>
                                <h:link outcome="tagEdit.xhtml" value="#{msg.pointEditDetail_table_edit_tag}">
                                    <f:param name="pointId" value="#{point.id}"/>
                                </h:link>
                            </center>
                        </rich:column>
                        <f:facet name="footer">
                            <rich:dataScroller for="pointtable" />
                        </f:facet>
                    </rich:dataTable>

                </h:form>
            </rich:panel>
        </rich:tab>
        <rich:tab header="Daten">
            <h:form>
                <rich:panel id="legendpanel">
                    <f:facet name="header">
                        #{msg.pointEditDetail_legend_edit_header }
                    </f:facet>

                    <h:outputText rendered="#{not empty pointEdit.legendeStatus}"
                        value="#{msg.pointEditDetail_legend_edit_success}" />
                    <br />
                    <h:inputTextarea value="#{pointEdit.legende}" cols="40" rows="8"/> <br /> <br />
                    <a4j:commandButton value="#{msg.pointEditDetail_legend_edit_button} " 
                        render="legendpanel legende" action="#{pointEdit.editLegend}" />
                </rich:panel>
            </h:form>
            <br />
            <h:form>
                <rich:panel name="labelPanel">
                    <f:facet name="header">
                        #{msg.pointEditDetail_label_edit_header }
                    </f:facet>
                    <rich:dataTable value="#{pointEdit.labels}" var="label"
                        id="labelTable" rows="10">
                        <rich:column>
                            <f:facet name="header">
                                Id
                            </f:facet>
                            #{label.id }
                        </rich:column>
                        <rich:column>
                            <f:facet name="header">
                                #{msg.pointEditDetail_label_edit_table_header}
                            </f:facet>
                            <rich:inplaceInput value="#{label.labelText }" showControls="true" layout="block" style="width: 98%"
                                 required="true">
                                 <a4j:ajax event="change" render="pointtable" listener="#{pointEdit.editLabel(label.id) }" />
                            </rich:inplaceInput>
                        </rich:column>

                        <f:facet name="footer">
                            <rich:dataScroller for="labelTable" />
                        </f:facet>
                    </rich:dataTable>

                </rich:panel>
            </h:form>
            <br />
        </rich:tab>
        <rich:tab header="Verknüpfen">
            <ui:include src="linkFigures.xhtml" />
        </rich:tab>
    </rich:tabPanel>
    <script type="text/javascript" src="javascript/eprometheus.js"></script>
</body>
</html>
4

2 回答 2

2

您需要像在命令链接一样传递该参数,<f:param>以便它保留在后续请求中:

<h:commandLink>
    <f:param name="figureId" value="#{pointEdit.figureId}" />
</h:commandLink>

在继续之前检查init()if FacesContext#isPostback()equal to false(以便它仅在新的新 GET 请求上运行,而不是在后续回发中,因为 bean 是视图范围的并且属性已经设置):

public void init() {
    if (!FacesContext.getCurrentInstance().isPostback()) {
        // ...
    }
}
于 2011-09-14T15:01:02.063 回答
0

我的新测试图像比我进行 4 次测试的图像大 5 倍。在我的 ViewScoped bean 中,我将图形作为属性,因此必须对整个 byte[] 进行序列化。消除此设计缺陷后,它再次起作用,并解释了为什么新图像会引起麻烦!

于 2011-09-15T14:45:40.693 回答