【问题标题】:How to marshall a javax.xml.datatype.Duration Java <--> JS using Spring/DWR如何使用 Spring/DWR 编组 javax.xml.datatype.Duration Java <--> JS
【发布时间】:2013-04-26 18:57:21
【问题描述】:

我得到了一个非常复杂的生成类堆栈,需要使用 DWR 在服务器和客户端之间发送它。其中一个类使用 jax.xml.datatype.Duration。这是我使用持续时间创建带有测试数据的 bean 的 Java 代码:

DatatypeFactory df = DatatypeFactory.newInstance();
Duration duration = df.newDuration(RANDOM.nextLong());
testObject.setDuration(duration);

DWR 不喜欢对象中的持续时间:

错误 [org.directwebremoting.dwrp.DefaultConverterManager] - 找不到“com.sun.org.apache.xerces.internal.jaxp.datatype.DurationImpl”的转换器

偶尔我会看到类 com.sun.org.apache.xerces.internal.jaxp.datatype.DurationImpl 的相同消息(我想是在我从 JavaScript 回到 Java 时)

定义常规转换器没有帮助:

<dwr:convert type="bean" match="com.sun.org.apache.xerces.internal.jaxp.datatype.DurationImpl"/>
<dwr:convert type="bean" match="javax.xml.datatype.Duration"/>

我确定上述方法不起作用,因为它们不是真正的豆子。但我不知道如何让它发挥作用。我在几个地方读过你可以定义一个自定义转换器,但细节似乎很模糊,在大多数情况下已经过时了。 DWR 网站说有一个链接可以解释这一切,但它只是将您链接到 javadoc,这对我的实际实现没有帮助。

谁能帮我弄清楚如何处理持续时间?

【问题讨论】:

    标签: java javascript spring marshalling dwr


    【解决方案1】:

    我找不到提供答案的地方,所以我不得不将来自不同地方的一些信息拼凑在一起——spring-dwr 架构、扩展所提供的类的示例等。

    对于初学者来说,这是配置 spring.xml 的正确方法:

      <dwr:configuration>
        <dwr:init>
            <dwr:converter id="durationConverter" class="com.foo.DurationConverter"/>
        </dwr:init>
    
        <dwr:convert class="com.sun.org.apache.xerces.internal.jaxp.datatype.DurationImpl" type="durationConverter"/>
        <dwr:convert class="javax.xml.datatype.Duration" type="durationConverter"/>
        ...
      </dwr:configuration>
    

    我不确定我是否需要 DurationImpl 和 Duration 转换声明,但我已经看到了它们的消息,所以我把它们都放进去了。

    这是我构建转换器的方法:

    public class DurationConverter extends BeanConverter {
    
        @Override
        public Duration convertInbound(Class<?> type, InboundVariable iv, InboundContext ic) throws MarshallException {
            String value = iv.getValue();
    
            // If the text is null then the whole bean is null
            if (value == null) {
                return null;
            }
    
            Duration duration = null;
            try {
                DatatypeFactory df = DatatypeFactory.newInstance();
                duration = df.newDuration(Long.valueOf(value));
    
            } catch (DatatypeConfigurationException ex) {
                Logger.getLogger(DurationConverter.class.getName()).log(Level.SEVERE, null, ex);
            }
    
            return duration;
        }
    
        @Override
        public OutboundVariable convertOutbound(Object o, OutboundContext oc) throws MarshallException {
            Duration duration = (Duration) o;
            String varname = oc.getNextVariableName();
            Map<String, OutboundVariable> ovs = new TreeMap<>();
            OutboundVariable durationOV = getConverterManager().convertOutbound(duration.getSeconds(), oc); 
    
            ovs.put("duration", durationOV);
    
            ObjectJsonOutboundVariable oj = new ObjectJsonOutboundVariable();
            oj.setChildren(ovs);
    
            return oj;
        }
    }
    

    希望这可以帮助其他人在同样的事情上挣扎。

    【讨论】:

      【解决方案2】:

      我不知道 DWR,但在查看 com.sun.org.apache.xerces.internal.jaxp.datatype.DurationImpl 时,没有公共默认构造函数,我之前在类似的 JAXB 中看到过此类问题情况。在 JAXB 中,我在包中使用 package-info.java 文件,该文件包含包含在您的案例持续时间中的对象定义(在我的案例中为 java.util.Locale)。我的对象存储在 com.foo.domain 中。

      @XmlJavaTypeAdapter(type = java.util.Locale.class, value=com.foo.util.LocaleXmlAdapter.class)
      package com.foo.domain;
      import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
      

      现在我的 LocaleXmlAdapter.class 定义

      public class LocaleXmlAdapter extends XmlAdapter<String, Locale> {
          @Override
          public Locale unmarshal(String localeString) throws Exception {
              {insert your impl}
          }
      
          @Override
          public String marshal(Locale locale) throws Exception {
              {insert your impl}
          }
      }
      

      这允许 JAXB 解决缺少默认构造函数的问题。

      【讨论】:

      • 非常相似的问题的好建议和解决方案。不幸的是,这解决了 Java 和 XML 之间编组的 jaxb 问题。我需要告诉 DWR 如何处理 Java 和 JavaScript 之间的编组。
      • 是的,我明白了。快速查看源代码,您可能需要进行一些修改才能使您的东西正常工作,请查看源代码中的这个包,它看起来很有希望,因为它们具有用于其他没有默认构造函数的类的转换器。 svn.directwebremoting.org/dwr/trunk/core/impl/main/java/org/…
      猜你喜欢
      • 1970-01-01
      • 2015-08-28
      • 1970-01-01
      • 1970-01-01
      • 2010-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-18
      相关资源
      最近更新 更多