好的,这就是我现在所知道的。这几个月来一直是我的问题。
首先,您必须更改 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));
}
现在是 Bridge 实现...
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) 的阅读,这是到达 marshaller 的唯一方法。
NOTE2 RI final 类有一个向下转换。这仅适用于参考实现。 YMMV