1

生成されたクラスのかなり複雑なスタックが与えられ、DWR を使用してサーバーとクライアントの間で送信する必要があります。クラスの 1 つは 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のWebサイトには、すべてを説明するリンクがあると書かれていますが、実際の実装には役立たないjavadocにリンクしているだけです。

期間を処理する方法を理解するのを手伝ってくれる人はいますか?

4

2 に答える 2

2

答えを提供してくれる場所が 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 convert 宣言の両方が必要かどうかはよくわかりませんが、両方のメッセージを見たので、両方を入れました。

コンバーターの作成方法は次のとおりです。

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;
    }
}

これが同じことで苦労している他の誰かに役立つことを願っています。

于 2013-04-30T13:27:20.613 に答える
1

私は DWR を知りませんが、com.sun.org.apache.xerces.internal.jaxp.datatype.DurationImpl を見ると、公開されているデフォルトのコンストラクターはなく、以前に同様の状況で JAXB に関するこの種の問題を見たことがあります。JAXBでは、ケースの期間(私の場合はjava.util.Locale)に含まれるオブジェクト定義を含むパッケージでpackage-info.javaファイルを使用します。私のオブジェクトは 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 はデフォルト コンストラクターの欠如を解決できます。

于 2013-04-26T21:00:45.103 に答える