1

我正在尝试List<String>使用一个简单的示例在一个中插入多个 IP。但我收到以下错误。

javax.el.PropertyNotFoundException:目标无法到达,'BracketSuffix' 返回 null

这是我的 JSF 2.2 页面:

<h:form id="form">
    <ui:repeat value="#{exampleBean.ipAddresses}" var="s"
        varStatus="status">
        <h:inputText value="#{exampleBean.ipAddresses[status.index]}" />
    </ui:repeat>
    <h:inputText value="#{exampleBean.newIp}" />
    <h:commandButton value="Add" action="#{exampleBean.add}" />
    <h:commandButton value="Save" action="#{exampleBean.save}" />
</h:form>

这是我的支持bean:

@ManagedBean
@ViewScoped
public class ExampleBean implements Serializable {

    private static final long serialVersionUID = 1L;
    private List<String> ipAddresses;
    private String newIp;

    @PostConstruct
    public void init() {
        ipAddresses= new ArrayList<String>();
    }

    public String save() {
        System.out.println(ipAddresses.toString());
        return null;
    }

    public void add() {
        ipAddresses.add(newIp);
        newIp = null;
    }

    public List<String> getIpAddresses() {
        return ipAddresses;
    }

    public String getNewIp() {
        return newIp;
    }

    public void setNewIp(String newIp) {
        this.newIp = newIp;
    }

}

这是如何引起的,我该如何解决?

4

1 回答 1

2

javax.el.PropertyNotFoundException:目标无法到达,'BracketSuffix' 返回 null

异常消息是错误的。这是服务器使用的 EL 实现中的一个错误。在您的具体情况下,它的真正含义是:

javax.el.PropertyNotFoundException:目标不可达,'ipAddresses [status.index]'返回空

换句话说,数组列表中没有这样的项目。这表明 bean 在表单提交时重新创建,因此将所有内容重新初始化为默认值。因此它的行为就像@RequestScoped一个。很可能您导入了错误的@ViewScoped注释。对于 a @ManagedBean,您需要确保@ViewScoped从同一个javax.faces.bean包导入,而不是 JSF 2.2 引入javax.faces.view的专门用于 CDI @Namedbean 的包。

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

也可以看看:


更新:根据评论,您使用的是 WebSphere 8.5,它通常附带一个古老的 MyFaces 2.0.x 版本。我用 MyFaces 2.0.5 重现了您的问题。它<ui:repeat>无法记住迭代状态的视图状态,这就是即使您正确使用@ViewScopedbean,您的构造仍然失败的原因。我可以通过使用来解决它<c:forEach>

<c:forEach items="#{exampleBean.ipAddresses}" var="s" varStatus="status">
    ...
</c:forEach>

另一种解决方案(显然,除了将 MyFaces 升级到更新/体面的版本之外)是将不可变对象包装String在可变的 javabean 中,例如

public class IpAddress implements Serializable {
    private String value;
    // ...
}

这样您就可以使用List<IpAddress>而不是,List<String>因此您不再需要varStatus触发 MyFaces 错误的。

private List<IpAddress> ipAddresses;
private IpAddress newIp;

@PostConstruct
public void init() {
    ipAddresses= new ArrayList<IpAddress>();
    newIp = new IpAddress();
}

<ui:repeat value="#{exampleBean.ipAddresses}" var="ipAddress">
    <h:inputText value="#{ipAddress.value}" />
</ui:repeat>
<h:inputText value="#{exampleBean.newIp.value}" />
于 2016-02-16T19:57:05.210 回答