PrimeFaces SelectOneMenu Converter 损坏组件

发布于 2025-01-15 08:46:25 字数 6356 浏览 0 评论 0原文

给定组件: https://www.primefaces.org/showcase/ui/ input/oneMenu.xhtml

我的测试的完整源代码位于:https://github.com/dannymk/PrimefacesTest

无法让组件使用转换器来处理对象。不知道如何解决这个问题。

package org.primefaces.test;

import java.io.Serializable;

public class Player implements Serializable {

    private Integer id;
    private String name;
    
    Player(Integer id, String name){
        this.id = id;
        this.name = name;
    }
    
    /**
     * @return the id
     */
    public Integer getId() {
        return id;
    }

    /**
     * @param id the id to set
     */
    public void setId(Integer id) {
        this.id = id;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

}
package org.primefaces.test;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Daniel Maldonado
 */
public class PlayerService implements Serializable{

    private List<Player> available = new ArrayList<>();
    
    public PlayerService() {
        available.add(new Player(1, "One"));
        available.add(new Player(2, "Two"));
        available.add(new Player(3, "Three"));
        available.add(new Player(4, "Four"));
        available.add(new Player(5, "Five"));
        
    }

    /**
     * @return the available
     */
    public List<Player> getAvailable() {
        return available;
    }

    /**
     * @param available the available to set
     */
    public void setAvailable(List<Player> available) {
        this.available = available;
    }
    
    
}
package org.primefaces.test;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.inject.Inject;
import javax.inject.Named;

/**
 *
 * @author Daniel Maldonado
 */
@Named
@FacesConverter(value = "playerConverter", managed = true)
public class PlayerConverter implements Converter<Player> {
    
   @Inject
   PlayerService service;
   
   @Override
   public Player getAsObject(FacesContext context, UIComponent component, String value) {
      if (value != null && value.trim().length() > 0) {
         Player found = service.getAvailable().stream()
            .filter(player -> player.getName().equals(value))
            .findAny()
            .orElse(null);

         return found;
      }
      return null;
      
   }

   @Override
   public String getAsString(FacesContext context, UIComponent component, Player o) {
      if (o != null){
         return o.getName();
        }
      return null;
      
   }    

}
package org.primefaces.test;

import java.io.Serializable;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;

import lombok.Data;

@Data
@Named
@ViewScoped
public class TestView implements Serializable {
    
    private String hello;
     
     private List<Player> available;
     private Player selected;
     
     @Inject
     PlayerService service;
    
    @PostConstruct  
    public void init() {
        setHello("Welcome to PrimeFaces!!!");
        this.available = service.getAvailable();
          
    }

    /**
     * @return the available
     */
    public List<Player> getAvailable() {
        return available;
    }

    /**
     * @param available the available to set
     */
    public void setAvailable(List<Player> available) {
        this.available = available;
    }

    /**
     * @return the selected
     */
    public Player getSelected() {
        return selected;
    }

    /**
     * @param selected the selected to set
     */
    public void setSelected(Player selected) {
        this.selected = selected;
    }

    /**
     * @return the hello
     */
    public String getHello() {
        return hello;
    }

    /**
     * @param hello the hello to set
     */
    public void setHello(String hello) {
        this.hello = hello;
    }

}
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://xmlns.jcp.org/jsf/core"
      xmlns:p="http://primefaces.org/ui"
      xmlns:h="http://xmlns.jcp.org/jsf/html">

    <h:head>
        <title>PrimeFaces Test - SelectOneMenu</title>
        <h:outputScript name="test.js" />
    </h:head>
    <h:body>

        <h1>#{testView.hello}</h1>
        <h:form id="frmTest">

            <p:panelGrid id="playerPanel" columns="2">
                <p:outputLabel value="Selected player: #{testView.selected.name}" />
                
                <p:selectOneMenu id="playerContainer" value="#{testView.selected}" var="p" converter="playerConverter" >
                    <f:selectItem itemLabel="Select One" itemValue="" />
                    <f:selectItems value="#{testView.available}" var="actual" itemLabel="#{actual.name}" itemValue="#{actual}" />
                    <p:column>
                            #{p.name}
                    </p:column>
                    <p:ajax event="valueChange" update="playerPanel" />
                </p:selectOneMenu>            

            </p:panelGrid>
            

        </h:form>

    </h:body>
</html>

我收到如下错误:

java.lang.ClassCastException: java.lang.String cannot be cast to org.primefaces.test.Player
        at org.primefaces.test.PlayerConverter.getAsString(PlayerConverter.java:38)

我更改的内容似乎并不重要,相信我,我已经尝试了转换器的大量实现,并且在视图中使用 "#{palyerConverter}" 而不是 " playerConverter” 但仍然无法让它工作。

Given the component: https://www.primefaces.org/showcase/ui/input/oneMenu.xhtml

Full source for my test is at: https://github.com/dannymk/PrimefacesTest

Can't get the component to work with an Object using a converter. Not sure how to solve this one.

package org.primefaces.test;

import java.io.Serializable;

public class Player implements Serializable {

    private Integer id;
    private String name;
    
    Player(Integer id, String name){
        this.id = id;
        this.name = name;
    }
    
    /**
     * @return the id
     */
    public Integer getId() {
        return id;
    }

    /**
     * @param id the id to set
     */
    public void setId(Integer id) {
        this.id = id;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

}
package org.primefaces.test;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Daniel Maldonado
 */
public class PlayerService implements Serializable{

    private List<Player> available = new ArrayList<>();
    
    public PlayerService() {
        available.add(new Player(1, "One"));
        available.add(new Player(2, "Two"));
        available.add(new Player(3, "Three"));
        available.add(new Player(4, "Four"));
        available.add(new Player(5, "Five"));
        
    }

    /**
     * @return the available
     */
    public List<Player> getAvailable() {
        return available;
    }

    /**
     * @param available the available to set
     */
    public void setAvailable(List<Player> available) {
        this.available = available;
    }
    
    
}
package org.primefaces.test;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.inject.Inject;
import javax.inject.Named;

/**
 *
 * @author Daniel Maldonado
 */
@Named
@FacesConverter(value = "playerConverter", managed = true)
public class PlayerConverter implements Converter<Player> {
    
   @Inject
   PlayerService service;
   
   @Override
   public Player getAsObject(FacesContext context, UIComponent component, String value) {
      if (value != null && value.trim().length() > 0) {
         Player found = service.getAvailable().stream()
            .filter(player -> player.getName().equals(value))
            .findAny()
            .orElse(null);

         return found;
      }
      return null;
      
   }

   @Override
   public String getAsString(FacesContext context, UIComponent component, Player o) {
      if (o != null){
         return o.getName();
        }
      return null;
      
   }    

}
package org.primefaces.test;

import java.io.Serializable;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;

import lombok.Data;

@Data
@Named
@ViewScoped
public class TestView implements Serializable {
    
    private String hello;
     
     private List<Player> available;
     private Player selected;
     
     @Inject
     PlayerService service;
    
    @PostConstruct  
    public void init() {
        setHello("Welcome to PrimeFaces!!!");
        this.available = service.getAvailable();
          
    }

    /**
     * @return the available
     */
    public List<Player> getAvailable() {
        return available;
    }

    /**
     * @param available the available to set
     */
    public void setAvailable(List<Player> available) {
        this.available = available;
    }

    /**
     * @return the selected
     */
    public Player getSelected() {
        return selected;
    }

    /**
     * @param selected the selected to set
     */
    public void setSelected(Player selected) {
        this.selected = selected;
    }

    /**
     * @return the hello
     */
    public String getHello() {
        return hello;
    }

    /**
     * @param hello the hello to set
     */
    public void setHello(String hello) {
        this.hello = hello;
    }

}
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://xmlns.jcp.org/jsf/core"
      xmlns:p="http://primefaces.org/ui"
      xmlns:h="http://xmlns.jcp.org/jsf/html">

    <h:head>
        <title>PrimeFaces Test - SelectOneMenu</title>
        <h:outputScript name="test.js" />
    </h:head>
    <h:body>

        <h1>#{testView.hello}</h1>
        <h:form id="frmTest">

            <p:panelGrid id="playerPanel" columns="2">
                <p:outputLabel value="Selected player: #{testView.selected.name}" />
                
                <p:selectOneMenu id="playerContainer" value="#{testView.selected}" var="p" converter="playerConverter" >
                    <f:selectItem itemLabel="Select One" itemValue="" />
                    <f:selectItems value="#{testView.available}" var="actual" itemLabel="#{actual.name}" itemValue="#{actual}" />
                    <p:column>
                            #{p.name}
                    </p:column>
                    <p:ajax event="valueChange" update="playerPanel" />
                </p:selectOneMenu>            

            </p:panelGrid>
            

        </h:form>

    </h:body>
</html>

I get errors like:

java.lang.ClassCastException: java.lang.String cannot be cast to org.primefaces.test.Player
        at org.primefaces.test.PlayerConverter.getAsString(PlayerConverter.java:38)

It does not seem to matter what I change and believe me I have tried plenty of implementations of the converter and in the view using "#{palyerConverter}" instead of "playerConverter" and still can't get it to work.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

空名 2025-01-22 08:46:25

您的问题出在这一行:

<f:selectItem itemLabel="Select One" itemValue="" />

当前您正在传递一个空字符串作为 itemValue,这不是您的转换器所期望的。使用 itemValue="#{null}" 或从无选择选项中完全删除 itemValue

另请参阅:

Your problem is at this line:

<f:selectItem itemLabel="Select One" itemValue="" />

Currently you are passing an empty string as the itemValue, which is not expected by your converter. Either use itemValue="#{null}" or totally remove the itemValue from the no select option.

See also:

白芷 2025-01-22 08:46:25

最后,由于@Jasper de Vries,只需进行一些更改即可使其正常工作:

<?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:f="http://xmlns.jcp.org/jsf/core"
      xmlns:p="http://primefaces.org/ui"
      xmlns:h="http://xmlns.jcp.org/jsf/html">

    <h:head>
        <title>PrimeFaces Test - SelectOneMenu</title>
        <h:outputScript name="test.js" />
    </h:head>
    <h:body>

        <h1>#{testView.hello}</h1>
        <h:form id="frmTest">

            <p:panelGrid id="playerPanel" columns="2">
                <p:outputLabel value="Selected player: #{testView.selected.name}" />
                <p:selectOneMenu id="playerContainer" value="#{testView.selected}" var="p" converter="playerConverter">
                    <f:selectItems value="#{testView.available}" var="actual" itemLabel="#{actual.name}" itemValue="#{actual}" />
                    <p:column>
                        #{p.name}
                    </p:column>
                    <p:ajax event="valueChange" update="playerPanel" />
                </p:selectOneMenu>

            </p:panelGrid>
            

        </h:form>

    </h:body>
</html>

特别是不要忘记在“列出”的对象中实现 EQUALS 方法:

package org.primefaces.test;

import java.io.Serializable;
import java.util.Objects;

public class Player implements Serializable {

    private Integer id;
    private String name;
    
    Player(Integer id, String name){
        this.id = id;
        this.name = name;
    }
    
   @Override
   public boolean equals(Object obj) {
          if(obj == null)
                  return false;

          if(!(obj instanceof Player))
                  return false;

          Player compare = (Player) obj;

          return Objects.equals(compare.getId(), this.getId());
   }

   @Override
   public int hashCode() {
          int hash = 1;
      return hash * 31 + this.getName().hashCode();
   }    
    
    /**
     * @return the id
     */
    public Integer getId() {
        return id;
    }

    /**
     * @param id the id to set
     */
    public void setId(Integer id) {
        this.id = id;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

}

Finally got it to work with just a few changes thanks to @Jasper de Vries:

<?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:f="http://xmlns.jcp.org/jsf/core"
      xmlns:p="http://primefaces.org/ui"
      xmlns:h="http://xmlns.jcp.org/jsf/html">

    <h:head>
        <title>PrimeFaces Test - SelectOneMenu</title>
        <h:outputScript name="test.js" />
    </h:head>
    <h:body>

        <h1>#{testView.hello}</h1>
        <h:form id="frmTest">

            <p:panelGrid id="playerPanel" columns="2">
                <p:outputLabel value="Selected player: #{testView.selected.name}" />
                <p:selectOneMenu id="playerContainer" value="#{testView.selected}" var="p" converter="playerConverter">
                    <f:selectItems value="#{testView.available}" var="actual" itemLabel="#{actual.name}" itemValue="#{actual}" />
                    <p:column>
                        #{p.name}
                    </p:column>
                    <p:ajax event="valueChange" update="playerPanel" />
                </p:selectOneMenu>

            </p:panelGrid>
            

        </h:form>

    </h:body>
</html>

and specially don't forget to implement the EQUALS method in the Object that is "listed":

package org.primefaces.test;

import java.io.Serializable;
import java.util.Objects;

public class Player implements Serializable {

    private Integer id;
    private String name;
    
    Player(Integer id, String name){
        this.id = id;
        this.name = name;
    }
    
   @Override
   public boolean equals(Object obj) {
          if(obj == null)
                  return false;

          if(!(obj instanceof Player))
                  return false;

          Player compare = (Player) obj;

          return Objects.equals(compare.getId(), this.getId());
   }

   @Override
   public int hashCode() {
          int hash = 1;
      return hash * 31 + this.getName().hashCode();
   }    
    
    /**
     * @return the id
     */
    public Integer getId() {
        return id;
    }

    /**
     * @param id the id to set
     */
    public void setId(Integer id) {
        this.id = id;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文