【问题标题】:Date conversion exception inside JSF composite componentJSF复合组件内的日期转换异常
【发布时间】:2011-05-30 08:09:21
【问题描述】:

当我从 JSF 访问 JPA 管理的日期值时,它返回一个 javax.faces.component.UdateModelException 说

'Cannot convert 01.01.10 00:00 of type class java.util.Date to class org.apache.openjpa.util.java$util$Date$proxy 

当直接从 EL 中使用时,使用 JPA 管理的日期值(这意味着它是代理的)可以正常工作:

'<h:outputLabel value="MyDateValue" for="input"/> 
'<h:inputText id="inputDate" value="#{bean.myDate}"/> 

但是,当尝试将它与复合组件一起使用时会导致麻烦 并返回以下转换器异常,因此无法更新模型...

(简化的)JSF 复合组件 inputDate.xhtml

    <head> 
            <title>A date input field</title> 
    </head> 

    <composite:interface> 
            <composite:attribute name="dateValue"/> 
    </composite:interface> 

    <composite:implementation> 
            <h:outputLabel value="MyDateValue" for="input"/> 
            <h:inputText id="input" value="#{cc.attrs.dateValue}"/> 
    </composite:implementation> 

假设: 当从组合内部访问值时,OpenJPA 中的代理替换的处理方式似乎有所不同。我的猜测是 EL 解析器在将对象值传递给组合时以不同方式处理对对象值的调用。将它传递给组合意味着它首先在组合中被访问,这为时已晚并且没有完成所需的代理替换(因此转换器异常)

所以我尝试更改 MyFaces 的表达式语言,但它在 Websphere 中不起作用,即使我最后将类加载更改为父级并在 lib 文件夹中从 glassfish 提供 el-impl 和 el-api 并插入MyFaces 的必要上下文参数

你们如何在复合组件中使用 JPA 管理的日期(或其他代理实体)???

【问题讨论】:

  • 您似乎暗示它在不使用复合组件时有效(因此,当直接在页面中“通常方式”使用组件时)。这是真的吗?
  • @BalusC 对。 “直接”使用它可以按预期工作。我发现 MyFaces Resolver 可以排序 cwiki.apache.org/MYFACES/elresolver-ordering.html 并用它玩了一点,但没有成功。使用不同的 ELFactoryImpl (JBoss El 2.0.1) 可以解决 JPA 代理日期的问题,尽管在 WebSphere 8 中注册它很棘手。但是方法调用不再适用于该 el...
  • 我以前从未见过这个问题,但我也没有使用 MyFaces。你有没有机会尝试 Mojarra 而不是 MyFaces,即使它只是为了排除一个和另一个。
  • @BalusC 不容易改,但我明天试试。仅供参考:我在 WebSphere 8 的 Beta 3 版本中将 MyFaces 与 OWB 和 OpenJPA 一起使用。所有使用的提供程序都是默认提供的,因此很难将 RI 更改为 Mojarra。欢呼
  • 嗯,好的。好吧,对不起,我只能说“祝你好运”。

标签: jsf-2 jpa-2.0 composite-component


【解决方案1】:

如果您使用的是 sun EL 实现,则可以使用以下 ELResolver 来解决此问题:

public class BugfixELResolver extends ELResolver {
//...
@Override
public Class<?> getType(ELContext anElContext, Object aBase, Object aProperty) {
    if (aBase.getClass().getCanonicalName().equals("com.sun.faces.el.CompositeComponentAttributesELResolver.ExpressionEvalMap")){
        Object tempProperty=((Map)aBase).get(aProperty);
        if (tempProperty!=null&&tempProperty.getClass().getCanonicalName().equals("org.apache.openjpa.util.java.util.Date.proxy")) {
            anElContext.setPropertyResolved(true);
            return java.util.Date.class;
        }
    }
    return null;
}


}

以这种方式将其添加到 faces-config 中:

<el-resolver>
    xxx.BugfixELResolver
</el-resolver>

此解决方法也可用于无法更改 EL 实现的环境(如 websphere 等)。

【讨论】:

  • 不错的解决方法。但是它在新的 webpshere 版本中得到了解决。我会将您的解决方案标记为已接受
【解决方案2】:

这是解决方法。问题似乎是 WebSpheres 的 ExpressionLanguage 实现,或者更确切地说是执行顺序解析器。注册 JBoss EL 实现工作并在调用复合组件之前解析日期代理。我也试过 Glassfish EL,但也没有用...

注册一个替代EL很奇怪:web.xml中MyFaces的设置是

<context-param>
   <param-name>org.apache.myfaces.EXPRESSION_FACTORY</param-name>
   <param-value>org.jboss.el.ExpressionFactoryImpl</param-value>
</context-param>

WebContent/META-INF/services/ 下还需要一个名为javax.el.expressionFactory 的文件,其中包含这一行org.jboss.el.ExpressionFactoryImpl。课程来自jboss-el-2.0.2.CR1.jar (抱歉,找不到 maven repo 的链接)

一旦找到更好的解决方案,我会及时通知您...

【讨论】:

  • 更新:原来是 Websphere 的 el 问题,目标是在 8.0.0.2 版本中修复
猜你喜欢
  • 1970-01-01
  • 2013-08-22
  • 1970-01-01
  • 1970-01-01
  • 2018-11-29
  • 2012-02-20
  • 2015-07-11
相关资源
最近更新 更多