【问题标题】:JSF does not convert LinkedHashMap to the correct object (javax.el.MethodNotFoundException)JSF 不会将 LinkedHashMap 转换为正确的对象 (javax.el.MethodNotFoundException)
【发布时间】:2016-07-05 11:01:07
【问题描述】:

我有一个 JSF 应用程序,一切正常,除了调用 ManagedBean 中以对象为参数的方法:

<p:dataTable value="#{sContr.privileges}" var="privilege">
    <p:column>
        <h:outputText value="#{privilege.name}"/>
    </p:column>
    <p:column>
        <h:outputText value="#{privilege.description}"/>
    </p:column>
    <p:column>
        <h:commandButton action="#{sContr.deletePrivilege(privilege)}" image="somePath"/>
    </p:column>
</p:dataTable>

在 sContr 中:

public void deletePrivilege(Privilege privilege) {
    System.out.println("test");
}

没有自己定义的对象的所有方法都可以工作(例如 Maps、Strings、Lists 等),并且访问 xhtml 中的对象甚至子对象都非常有效。
但是,调用此 deletePrivilege 会导致:

javax.servlet.ServletException: javax.el.MethodNotFoundException: [...]privileges.xhtml @31,138 action="#{sContr.deletePrivilege(privilege)}": Method not found: [...]sContrl@604b7816.deletePrivilege(java.util.LinkedHashMap)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:659)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
[...]

这些对象是在 JSF 应用程序之外的另一个模块中定义的,并且是普通的 java 对象(没有特定的 JSF 注释)。

因此,出于某种原因,JSF 无法将 LinkedHashMap 自动转换回用于呈现页面的类的实例。

faces-config.xml:

<?xml version='1.0' encoding='UTF-8'?>
<faces-config xmlns="http://xmlns.jcp.org/xml/ns/javaee"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
    http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"
              version="2.2">

    <managed-bean>
        <managed-bean-name>currentDate</managed-bean-name>
        <managed-bean-class>java.util.Date</managed-bean-class>
        <managed-bean-scope>request</managed-bean-scope>
    </managed-bean>

    <application>
        <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
    </application>
</faces-config>

maven 包括 JSF 和 primefaces:

<dependency>
    <groupId>com.sun.faces</groupId>
    <artifactId>jsf-api</artifactId>
    <version>2.2.6</version>
</dependency>
<dependency>
    <groupId>com.sun.faces</groupId>
    <artifactId>jsf-impl</artifactId>
    <version>2.2.6</version>
</dependency>
<dependency>
    <groupId>org.primefaces</groupId>
    <artifactId>primefaces</artifactId>
    <version>5.1</version>
</dependency>
<dependency>
    <groupId>org.primefaces.extensions</groupId>
    <artifactId>primefaces-extensions</artifactId>
    <version>2.1.0</version>
</dependency>
<dependency>
    <groupId>org.primefaces.themes</groupId>
    <artifactId>all-themes</artifactId>
    <version>1.0.10</version>
</dependency>

我的对象:

@Entity
public class Privilege implements IEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column()
    private Long id;
    @Column()
    private String name;
    @Column()
    private String description;

    public Privilege(String name) {
        this.name = name;
    }

    public Privilege(Long id, String name) {
        this.id = id;
        this.name = name;
    }

    public Privilege(Long id, String name, String description) {
        this(id, name);
        this.description = description;
    }

    public Privilege() {

    }

    @Override
    public Long getId() {
        return id;
    }

    @Override
    public void setId(Long id) {
        this.id = id;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(final String description) {
        this.description = description;
    }
}

还要澄清一下:LinkedHashMap 包含 id、名称和描述(因此它应该具有构建正确对象的所有内容)

这可能是什么问题?我需要在 faces-config 中以某种方式定义包吗?

使用:Mojarra 2.2.6、primefaces 5.1、primefaces-extensions 2.1.0

【问题讨论】:

  • 所以它适用于h:dataTable?你的豆子在哪里?据我们所知,sContr.privileges 是一个 hashMaps 列表,JSF 是对的,而你错了。请说明明确的版本信息。另见stackoverflow.com/tags/jsf/info
  • private List&lt;Privilege&gt; privileges; 并实例化为 ArrayList。一切都正确显示。 sContr 是注释为 @ManagedBean @SessionScoped 的 ManagedBean,除自定义对象外,其中的每个方法都有效。我在问题中添加了版本的maven设置
  • 并澄清:一切正常,除了:action="#{sContr.deletePrivilege(privilege)}"。不会将对象发送到 sContr 的其他操作(例如 action="#{sContr.createDefaultPrivilege()}")可以正常工作
  • 您使用的是什么 EL 版本和实现?
  • LinkedHashMap 在哪里使用?请...minimal reproducible example(带有最小实体等...)。您的标题和文字提到了您的代码中无处可见的内容......例如为什么这个 “还要澄清一下:LinkedHashMap 包含 id、名称和描述(因此它应该拥有构建正确对象的一切)”

标签: jsf jsf-2 primefaces


【解决方案1】:

这取决于您如何解决特权,所以如果您要反序列化它可能会如何,我遇到了同样的问题,我正在使用 jackson 从 json 反序列化设备模型

class Device{}
devices = objectMapper.readValue(responseBody, List.class);

它给出了完全相同的错误 我解决反序列化之类的

devices = objectMapper.readValue(responseBody, new TypeReference<>() {});

而且效果很好。

【讨论】:

  • 对不起,这与原问题完全无关
猜你喜欢
  • 2013-03-04
  • 1970-01-01
  • 1970-01-01
  • 2018-12-05
  • 1970-01-01
  • 2012-05-14
  • 2014-04-17
  • 2019-10-14
  • 2014-10-26
相关资源
最近更新 更多