转换错误:为“null转换器”设置“UserID”值。

4

当我试图从应用程序中的表格中删除或编辑用户时,出现了转换错误。值是从listUser.xhmtl传递到deleteUser.xhtml页面的元数据。尽管值已经在元数据中传递,但在调用删除操作时,我会收到“Conversion Error setting value "someemail@somedomain.com" for 'null Converter'”的错误提示。用户ID是一个字符串。

请求userDelete.xhmtl后的URL如下:

http://localhost:8080/lavpWebApp/user/deleteUser.xhtml?user=someemail%40somedomain.com

这是经过简化的userList.xhmtl文件:
<h:column>
                            <f:facet name="header">Edit</f:facet>
                            <h:link outcome="/user/editUser.xhtml" value="Edit User">
                                <f:param name="user" value="#{item.email}"/>
                            </h:link>                            
                        </h:column>

                        <h:column>
                            <f:facet name="header">Delete</f:facet>
                            <h:link outcome="/user/deleteUser.xhtml" value="Delete User">
                                <f:param name="user" value="#{item.email}"/>
                            </h:link>
                        </h:column>

这是简化后的userDelete.xhtml页面:
<f:metadata>
        <f:viewParam name="user" value="#{userController.user}" converter="#{userConverter}"/>
    </f:metadata>

    <h:body>
        Do you want to delete #{userController.user.name}?
        <h:form>
            <h:commandButton action="#{userController.deleteUser()}"
                             value="Delete"/>
            <h:commandButton action="#{userController.doCancelDeleteUser()}"
                             value ="Cancel"/>
        </h:form>
    </h:body>

这是转换器类(Converter class):
@ManagedBean
@FacesConverter(value="userConverter")
public class UserConverter implements Converter{

    @EJB
    private UserSellerEJB userEjb;

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        if (value == null || value.isEmpty())
        {
            return null;
        }
        if(!value.matches("\\d+"))
        {
            throw new ConverterException("The value is not a valid email: " + value);
        }

        String id = value.toString();
        return userEjb.findUserById(id);

    }

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

        if(!(value instanceof UserSeller))
        {
            throw new ConverterException("The value is not a User: " + value);            
        }

        String id = ((UserSeller) value).getEmail();
        return (id != null) ? id.toString() : null;
    }

}

这是简化后的userController类:

@Named
@RequestScoped
public class UserController{

    @EJB
    private UserSellerEJB userEJB;

    private UserSeller user = new UserSeller(); 
    private List<UserSeller> usersList = new ArrayList<UserSeller>();

    // ------------------------------------------------------------- Constructor
    public UserController() {
    }

    // -------------------------------------------------------- Business Methods

    public String doCreateUser()
    {
        user = userEJB.createSeller(user);
        usersList = userEJB.findAllSellers();
        return "listUser?faces-redirect=true";        
    }

        // update user

        public void PreRenderView()
        {
            if(user == null)
            {
                user = new UserSeller();
            }            
        }

        public String doUpdateUser()
        {
            if(user.getEmail() != null)
            {
                userEJB.updateSeller(user);
            }
            else
            {
                userEJB.createSeller(user);
            }

            return "listUser?faces-redirect=true";
        }

    public String deleteUser()
    {
        userEJB.deleteSeller(user);
        return "listUser?faces-redirect=true";
    }

    public String doCancelDeleteUser()
    {
        return "listUser?faces-redirect=true";
    }


    @PostConstruct
    public void init()
    {
        usersList = userEJB.findAllSellers();       
    }

尝试为@ManagedBean注释分配一个“名称”,并使用该名称来访问转换器。确保它与您已在@FacesConverter中使用的名称不同。 - kolossus
@kolossus 谢谢。我已经将 name 添加到 @ManagedBean 中,我使用了 @ManagedBean(name="userSellerConverter") 但仍然出现相同的错误。 - lv10
@LuiggiMendoza,看到了获胜答案。还看到了https://dev59.com/WXI-5IYBdhLWcg3wFkSO#8919591。我不是说它很漂亮或正确,但它是可行的。 - kolossus
@kolossus在使用您的建议并重启服务器后,我得到了这个错误"{0}: 转换错误发生。" 先行致谢。 - lv10
1
从技术上讲,Luiggi 是正确的,一个 @ManagedBean 不能有一个 @FacesConverter 注解。通常情况下只能选择其中一种,而不是两者都有。 - BalusC
显示剩余6条评论
1个回答

5
在异常消息中,null转换器表示找不到转换器实例。由于您正在将转换器作为托管bean引用,如converter="#{userConverter},只有在使用@javax.faces.bean.ManagedBean进行注释并且类位于WAR(因此不在EJB / EAR或其他地方!)的情况下才能找到它。

在这种构造中没有使用@FacesConverter注释,实际上是多余的-对初学者来说只会令人困惑。请删除该注释。@EJB确实仅适用于托管bean。

如果真的徒劳无功(但我无法解释原因),请尝试通过CDI进行管理:将JSF @ManagedBean注释替换为CDI @Named注释。您显然已经通过CDI成功管理前端控制器bean。


与具体问题无关,转换器似乎是根据技术ID(DB主键)进行转换设计的,而不是电子邮件地址。电子邮件地址永远不可能与\d+(这是仅限数字的正则表达式)匹配。确保您没有混淆电子邮件地址和ID。


非常感谢您详细的建议。我已经按照您的指示进行了操作,删除了@FacesConverter注释,并将@ManagedBean注释替换为@Named("userConverter")。我还删除了正则表达式条件。我现在使用电子邮件作为此“User”的ID,这就是我使用电子邮件的原因。问题现已解决。非常感谢。 - lv10
BalusC - 一个问题:我是 JSF 的新手,并且已经了解到 @FacesConverter 是必需的,想要充分理解为什么我在这种情况下需要将其移除。你能否详细说明一下为什么我们要为这个转换器移除它?- 预先感谢。 - lv10
1
那是因为你想在其中注入一个 @EJB。然而,@FacesConverter(和 @FacesValidator)不是受支持的注入目标。这个疏忽在即将发布的 JSF 2.2 中得到了修复。 - BalusC
非常感谢,我现在明白了。 - lv10

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接