わかりました、これが私が今知っていることです。これは私にとって何ヶ月も問題でした。
まず、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