1

我正在使用与 Java 6 SE 捆绑在一起的 Metro 堆栈来调用 Web 服务。Web 服务需要 XML 作为参数。我使用 JAXB 类来创建内容并将我的 JAXB 根​​元素传递给 Web 服务端点。

现在我的问题:我找不到任何方法让编组器包含 XSD 文件的 schemaLocation,因为我无法直接访问编组器。(如果您可以直接访问编组器,则可以将 schemalocation 设置为属性,但是在使用 Metro 时,所有编组似乎都在内部进行。)

我尝试在生成的 package-info.java 类的 XmlSchema 注释中设置 xsi:schemaLocation ,但这对生成的 xml 没有影响。

还有一点是,在 Java SE 环境中创建 Web 服务客户端和调用 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)的阅读,这是到达编组器的唯一方法。

注2 RI 最终类有一个向下转换。这仅适用于参考实现。YMMV

于 2012-10-10T15:26:51.927 回答