Java 在JSF中选择时“切换”bean的最佳方法

Java 在JSF中选择时“切换”bean的最佳方法,java,jsf,jsf-2,Java,Jsf,Jsf 2,我有一个bean播放器,当我在SelectOne菜单中选择一个值时,我想切换到数据库中匹配的bean 我已将bean发送回中的select one菜单 public List<Player> getAllPlayers() { } 已将下拉列表更新到此位置 但我仍然无法让它将ID发送到转换器。它将发送玩家的名字 @FacesConverter(value = "playerConverter") public class PlayerConverter implements Con

我有一个bean播放器,当我在SelectOne菜单中选择一个值时,我想切换到数据库中匹配的bean

我已将bean发送回中的select one菜单

public List<Player> getAllPlayers() { }
已将下拉列表更新到此位置

但我仍然无法让它将ID发送到转换器。它将发送玩家的名字

@FacesConverter(value = "playerConverter")
public class PlayerConverter implements Converter {

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        if (value == null) {
            return null;
        }

        long idValue;
        try {
            idValue = Long.parseLong(value);
        }
        catch (NumberFormatException ex)
        {
            return null;
        }

        ServicePlayer servicePlayer = context.getApplication()
                .evaluateExpressionGet(context, "#{servicePlayer}",
                        ServicePlayer.class);
        Player player = servicePlayer.getPlayerByID(idValue);
        return player;

    }

    @Override
    public String getAsString(FacesContext arg0, UIComponent arg1, Object value) {
        String string = null;
        if (value instanceof Player) {
            string = ((Player) value).getFirstName();
        }
        return string;
    }

}

public class ServicePlayer {

    private static final String PERSISTENCE_UNIT_NAME = "BowlingFacelets";
    public static EntityManagerFactory factory;
    Player myPlayer;

    public Player getMyPlayer() {
        return myPlayer;
    }


    public void setMyPlayer(Player myPlayer) {
        this.myPlayer = myPlayer;
    }


    public List<Player> getAllPlayers() {

        if (factory == null) {
            factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
        }

        EntityManager em = factory.createEntityManager();
        //Order by the matchdate.
        //Query q = em.createQuery("select t from DBTest t");
        Query q = em.createQuery("select t from Player t");

        List<Player> players = q.getResultList();
        for (Player aPlayer : players) {
          System.out.println(aPlayer);
        }
        System.out.println("Size: " + players.size());

        em.close();

        return players;
    }


public Player getPlayerByID(long id) {

        if (factory == null) {
            factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
        }

        EntityManager em = factory.createEntityManager();
        //Query q = em.createQuery("select t from Player t where t.name = '" + playerName + "'");
        //List<Player> players = q.getResultList();
        Player currentPlayer = em.find(Player.class, id);

        return currentPlayer;

    }


}

我认为您误解了selectOneMenu的value属性所指的内容。它的用途与所有其他输入组件一样,都是存储用户输入或从中获取现有值的位置

检查。您需要根据f:select项上的“var”属性设置键和值对,否则JSF无法真正了解您想要对Player对象做什么

因此,给定键/值对,键进入您设置为value属性的任何位置,值显示给用户,并且如果您使用player.id作为值,您可以根据该id获取用户。

JSF转换器将对象转换为itemValue属性的字符串值,然后从字符串值恢复该对象。对于您的情况,对象是播放器实体,而值是其id的字符串表示形式,只要您知道它是唯一的,就可以是其他任何形式

基本上,使用此转换器:

@FacesConverter(value = "playerConverter")
public class PlayerConverter implements Converter {

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        if (value == null) {
            return null;
        }

        long idValue;
        try {
            idValue = Long.parseLong(value);
        }
        catch (NumberFormatException ex)
        {
            return null;
        }

        ServicePlayer servicePlayer = context.getApplication()
                .evaluateExpressionGet(context, "#{servicePlayer}",
                        ServicePlayer.class);
        Player player = servicePlayer.getPlayerByID(idValue);
        return player;

    }

    @Override
    public String getAsString(FacesContext arg0, UIComponent arg1, Object value) {
        String string = null;
        if (value instanceof Player) {
            string = ((Player) value).getId();
        }
        return string;
    }

}
注意,我更改了您通过id返回的名称。这样,作为播放器id 1,JSF知道其字符串值为1。这是通过getAsString方法获得的选择值

当您发布表单时,JSF必须从1值恢复播放器实体,因此您可以使用Converter的getAsObject从DB加载它

这样,从视图中引用对象本身就足以让jsf进行转换:


我无法使用ID,因为我正在尝试。因为那不是人类可读的。在本例中,您建议我如何从SelectOne菜单中显示的player.firstName获取ID。无法保证数据库中只有一个名称实例。您可以使用id作为选项的值,并将标签设置为例如firstName。同样,标签是向用户显示的内容,以及您在逻辑中使用的值。仍然无法使其工作。添加了转换器和新的JSF代码。请尝试跳过转换器,而是将“String selectedPlayerId”引入ServicePlayer bean,并将其用作selectOneMenu的“值”。然后,在显示所选玩家时,根据“selectedPlayerID”中当前的id并使用getPlayerById。请参阅以获取下次的完整解决方案,请不要两次发布问题。其中一个目标是成为一个知识库,重复的东西会让事情变得更糟。事实上,这个问题并没有为我解决。另一个是。所以对我来说,它确实更好。我的意思是,最好只为线程维护一个帖子。如果您愿意,您可以编辑它并添加新的内容/测试案例,这将使文章与趋势案例保持一致。不要再按“提问”键了。