理解JSF转换器接口

时间:2015-07-27 20:00:07

标签: jsf jsf-2 converter hidden-field tomahawk

业务要求

我们必须让用户输入雇主的雇主姓名和雇主头衔(放入div可以说class =“empInfo”)。现在用户甚至可能有多个雇主,所以我们提供了一个按钮,点击它将创建另一个div(我基本上克隆了div)。

工作流程

表单起始页(用jsf编写的.xhtml文件),用户可以在其中输入表单的详细信息,包括雇主信息。 用户然后单击继续,然后他们进入审阅页面(也是另一个JSF页面),用户可以在其中查看添加/删除更多雇主信息。

我是如何解决这个问题的。

  1. 我们必须让用户输入雇主的雇主姓名和雇主名称。

    • 将两个文本字段放在div中,其中class =“empInfo”。
    • 使用Jquery添加/删除按钮以使用类
    • 克隆/删除div
  2. 将值放回托管bean中 这是它变得棘手的地方(对我来说,考虑到我在J2ee,特别是JSF方面的经验相对较少)。

    • bean属性必须映射到两个ArrayList
      • 一个雇主姓名
      • 一个为雇主标题
    • 我无法编写forEach JSF / JSP标记,因为在克隆div后,这些值无法直接映射到后端。
    • 所以我添加了两个隐藏字段(每个bean属性一个)。
    • 当用户点击导航按钮转到另一个页面时,我使用JS通过class =“empInfo”收集div中的所有值,并设置两个隐藏值字段,该字段映射到数组列表豆子。
    • 我知道,视图中的值始终是String。
    • 所以我决定实现一个转换器将字符串转换为AL。
  3. 问题

    我无法将视图中的值成功传递给validater类中的重写转换器方法。

    JSF中的隐藏字段(使用tomahawk标签)

    <div class="XYZ">   
        <t:inputHidden value="#{Ctrlr.employerName}" id="eName" forceId="true" converter="jsArrayConverter"></t:inputHidden>        
    </div>
    

    转换器实施

    import javax.faces.convert.Converter;
    import javax.faces.component.UIComponent;
    import javax.faces.context.FacesContext;
    import javax.faces.convert.ConverterException;
    
    public class FMLAConverter implements Converter{
    
    @Override
    public ArrayList<String> getAsObject(FacesContext context, UIComponent   component,String ret) {
        System.out.println("Inside Converter function, getting value from the view    and putting it in the model");    
        System.out.println("I am working with "+ret +"Hmmm");
        ArrayList<String> list = new ArrayList<String>();
        int j=0;
        int i=ret.indexOf(',');
        int len = ret.length();
        if (i == -1){
            if(len==0){
                System.out.println(list);
                return list;
            }
            else
            {
                list.add(ret);
            }
        }
        while(i>0)
        {
            list.add(ret.substring(j,i));
            j=i+1;
            if(i+1<len)
                i = ret.indexOf(',', i+1);
            else
                i=-1;   
        }
        System.out.println(list);
        return list;
        }
    
        @Override
        public String getAsString(FacesContext context, UIComponent component,
            Object value) {
        ArrayList <String> list = (ArrayList <String>) value;
        int i=0;
        StringBuilder str= new StringBuilder();
        if(list==null)
            { 
                System.out.println("It is null");
                return str.append("").toString();
            }
        if(list.size()==0){
            System.out.println("Really");
            str.append("");
            return str.toString();
        }
    
        for(String string:list)
        {   
            if(i++==0)  
                str.append(string); 
            else
                str.append(",").append(string);         
        }
        System.out.println("Not bad");
        return str.toString();
        }
        }
    

    消除愚蠢的错误

    • JS正确地将值添加到隐藏字段。
    • 从Chrome控制台附加屏幕截图。

      google console screenshot

    调试步骤

    • 最近48小时工作,无法理解为什么它不起作用。在我的研究中,找不到任何东西。
    • 查看系统输出登录服务器,我看到了日志

        

      我正在与Hmmm合作

    • 所以我做了推断,隐藏字段的值是“”一个奇怪的空字符串。(除非我还没有完全理解JSF生命周期)

    • 可以肯定的是,我看到ret值是在用户点击表单中的下一个按钮之后。我在window.unload处添加了一个检查点,并从控制台拍摄了屏幕截图,所以JS很好。
    • 非常感谢任何帮助。我已经阅读了BALUS的教程(不是全部,但很多),这非常有用。而且JSF的任何其他链接或教程会更有帮助。

1 个答案:

答案 0 :(得分:0)

如果提交的值为null或为空,则表示webbrowser没有发送预期的输入值。 JSF转换器中没有任何代码逻辑可以帮助解决这个问题。

退一步并相应地修改客户端代码,以便webbrowser实际发送预期的输入值。根据问题的评论,您可以在窗口unload事件期间设置值。那已经太晚了。当请求已经发送很长时间时会触发该事件。您需要在表单submit事件或提交按钮的click事件期间设置值。而不是摆弄浏览器的JS控制台,你最好从控制台选项卡到网络选项卡,并在那里检查HTTP请求有效负载。请求参数是否存在?

关于具体问题,在这个答案中详细解释了如何正确实施ConverterConversion Error setting value for 'null Converter'