具有属性值表达式语言的 JSF 2 自定义组件不会触发属性设置器 [英] JSF 2 Custom components having Expression Language for attribute value don't trigger the attribute setter

查看:13
本文介绍了具有属性值表达式语言的 JSF 2 自定义组件不会触发属性设置器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 JSF 2.0 中构建了一个自定义组件

I have build a custom component in JSF 2.0

标签如下所示:

<x:myTag id="1" name="AAA" />

对应的java类:

@FacesComponent("a.b.c.MyTag")
public class UIMyTag extends UIInput {

   private String name;
   private String id;

   public String getId() {
      return id;
   }

   public void setId(String id) {
       this.id = id;
   }


   public String getId() {
      return id;
   }

   public void setId(String id) {
       this.id = id;
   }

   public String getName() {
      return name;
   }

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

   @Override
   public void encodeBegin(FacesContext context) throws IOException {
       ResponseWriter writer = context.getResponseWriter();
       logger.debug(getName()); //prints null for name="#{dummyBean.name}" 
                                //   and AAA for name="AAA"
       logger.debug(getAttributes().get("name")); // always correct value
   ...
}
   ....

}

如果我使用

<x:myTag id="1" name="AAA" />

一切都按预期工作,但是当我将 EL 用于 myTag 属性时,setName() 方法永远不会被调用.所以对于,

everything works as expected, but when I use EL for myTag attributes the setName() method never gets called. So for,

<x:myTag id="#{dummyBean.id}" name="#{dummyBean.name}" />

我的 encodeBegin 方法中的 name 属性总是得到 null.调试后我注意到 setName 方法永远不会被调用.我想可能是关于 EL 的事情把事情搞砸了(我仍然相信原因与此有关),但真正奇怪的是 id 属性运行良好:setter 被调用,并且econding 开始时的值与预期一致.

I always get null for the name property inside my encodeBegin method. After debugging I've noticed that the setName method never gets called. I thought that maybe something regarding EL messes things up (and I still believe that the reason is related to that), but what's really weird is that the id property works good: the setter gets called, and the value is as expected when the econding begins.

我不得不提一下,如果我从 encodeBegin 方法调用 getAttributes().get("name") 我会得到正确的名称值,但我很好奇为什么它不适用于 getter 和 setter.

I have to mention that if I call getAttributes().get("name") from the encodeBegin method I get the correct name value, but I'm intrigued why it doesn't work with getter and setter.

知道我的组件缺少什么吗?

Any ideas what's missing to my component?

推荐答案

这种行为是预期的,也是规范所规定的.作为值表达式的属性值由 UIComponent#setValueExpression().它们应该只在真正被使用时才被评估,通常是在视图渲染时间.

This behavior is expected and by specification. Attribute values which are value expressions are set by UIComponent#setValueExpression(). They are namely supposed to be evaluated only when they are really been used, usually during view render time.

id(和 binding)属性有特殊的处理:它在视图构建时间之前被评估,所以常规" setter 将被调用而不是 setValueExpression()(因为当 id(或 binding)属性动态时,视图的呈现会崩溃由于某种原因,计算出的值与视图构建期间的值不同).

The id (and binding) attribute has special treatment: it's evaluated during view build time before it's been set, so the "regular" setter would be called instead of the setValueExpression() (because rendering of the view would otherwise crash when the id (or binding) attribute dynamically evaluates to a different value than it was during the view build time for some reason).

更好的是将 getter/setter 委托给 UIComponent#getStateHelper() 而不是本地属性.setValueExpression() 最终也会在 StateHelper 中结束(注意它根本不调用 setter;如果需要数据,只需调用 getter)和getAttributes() 也解析来自 StateHelper 的值.

Better is to delegate the getters/setters to UIComponent#getStateHelper() instead of to local properties. The setValueExpression() ultimately also end up in the StateHelper (note that it doesn't call the setter at all; just call the getter if you need the data) and the getAttributes() also resolves the values from the StateHelper.

public String getName() {
   return (String) getStateHelper().eval("name");
}

public void setName(String name) {
    getStateHelper().put("name", name);
}

请注意,您可以安全地删除getId()setId() 方法,因为它们已经在 UIComponentBase 您正在扩展的超类.

Note that you can safely remove the getId() and setId() methods, because they're already definied in the UIComponentBase superclass which you're extending from.

这篇关于具有属性值表达式语言的 JSF 2 自定义组件不会触发属性设置器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆