1

Java 6 SE にバンドルされている Metro スタックを使用して Web サービスを呼び出しています。Web サービスは、パラメーターとして XML を想定しています。JAXB クラスを使用してコンテンツを作成し、JAXB ルート要素を Web サービス エンドポイントに渡します。

今私の問題: マーシャラーに直接アクセスできないため、マーシャラーに XSD ファイルの schemaLocation を含める方法が見つかりません。(マーシャラーに直接アクセスできる場合は、スキーマの場所をプロパティとして設定できますが、metro を使用している場合は、すべてのマーシャリングが内部で行われているようです。)

生成された package-info.java クラスの XmlSchema アノテーションで xsi:schemaLocation を設定しようとしましたが、生成された xml には影響しませんでした。

もう 1 つのポイントは、Web サービス クライアントを作成し、Java SE 環境で Web サービスを呼び出すときに、@UsesJAXBContext、@WebServiceClient、@XmlSchema などの特定のアノテーションが無視されるように見えることです。(ここで、私はJava Webサービスに関して初心者であることを述べなければなりません)

4

1 に答える 1

2

わかりました、これが私が今知っていることです。これは私にとって何ヶ月も問題でした。

まず、JAX-WSで使用されるJAXBContextを変更する必要があります。これを行うには、サーバーで@UsesJAXBContextアノテーションを使用します。(com.sun.xml.ws.developer.UsesJAXBContext)

次に、ファクトリ実装で、このメソッドでカスタムブリッジを返す必要があります。

public Bridge createBridge(final TypeReference typereference)

次に、カスタムブリッジは、使用する名前空間マッパーを設定するためにmarshallerプロパティを設定する必要があります。

これが私の例です。

@WebService(serviceName = ...)
@UsesJAXBContext(MyContextFactory.class)
public class SoapServer { ... }

とファクトリークラス..。

public static class MyContextFactory implements JAXBContextFactory
{
    @Override
    public JAXBRIContext createJAXBContext(final SEIModel sei,
            @SuppressWarnings("rawtypes") final List<Class> classesToBind, final List<TypeReference> typeReferences)
            throws JAXBException
    {
        JAXBRIContext context = JAXBContextFactory.DEFAULT.createJAXBContext(sei, classesToBind, typeReferences);
        return new MyJaxwsContext(context);
    }
}

およびJAXBコンテキストの実装...

public class MyContext extends JAXBRIContext
{
/** the actual context */
private final JAXBRIContext delegate;

public MyContext(final JAXBRIContext createContext)
{
    this.delegate = createContext;
}

public Bridge createBridge(final TypeReference arg0)
{
    return new MyBridge((JAXBContextImpl) delegate, delegate.createBridge(arg0));
}

そして今、ブリッジの実装...

public class MyBridge extends Bridge
{
private final Bridge delegate;

protected MyBridge(final JAXBContextImpl context, final Bridge delegate)
{
    super(context);
    this.delegate = delegate;
}

// an example marshal call. There are many more...
public void marshal(final Marshaller m, final Object object, final ContentHandler contentHandler)
        throws JAXBException
{
    m.setProperty("com.sun.xml.bind.namespacePrefixMapper", namespaceMapper);
    delegate.marshal(m, object, contentHandler);
}

注:既存の実装をラップしました。私が欲しかったのは、名前空間名を修正できるようにすることだけでした。ソース(JAXWS)を読んだところ、これがマーシャラーにたどり着く唯一の方法です。

注2RIファイナルクラスへのダウンキャストがあります。これは、リファレンス実装でのみ機能します。YMMV

于 2012-10-10T15:26:51.927 に答える