JAXB无法处理接口 - 我漏掉了什么?

5

我正在使用Jax-ws(或JAXB,不确定)熟悉Java中的Web服务。

我创建了一个带有单个Web服务的小项目。该Web服务只有一个名为transfer的端点,并返回继承ITransferResult接口的对象。

Web服务合同

//Service Endpoint Interface
@WebService
@SOAPBinding(style = Style.RPC)
public interface IBankWebSrv {
    @WebMethod
    ITransferResult transfer(String accountNumber, double amount);
}

Web服务实现

//Service Implementation
@WebService(endpointInterface = "Contracts.IBankWebSrv")
public class BankWebSrv implements IBankWebSrv {
    @Override
    public ITransferResult transfer(String accountNumber, double amount) {
        ITransferResult result = new TransferResult();
        // TODO logic here
        result.setSuccessful(true);
        return result;
    }
}

转移结果合约

@XmlJavaTypeAdapter(TransferResult.class)
public interface ITransferResult {
    boolean isSuccessful();
    void setSuccessful(boolean successful);
}

TransferResult实现
public class TransferResult extends XmlAdapter<TransferResult, ITransferResult>
        implements ITransferResult {

    @XmlElement
    boolean successful;

    public boolean isSuccessful() {
        return this.successful;
    }

    public void setSuccessful(boolean successful) {
        this.successful = successful;
    }

    @Override
    public TransferResult marshal(ITransferResult v) throws Exception {
        return (TransferResult) v;
    }

    @Override
    public ITransferResult unmarshal(TransferResult v) throws Exception {
        return (ITransferResult) v;
    }
}

当我发布我的Web服务时,出现以下错误:

异常线程 "main" javax.xml.ws.WebServiceException: 无法创建JAXBContext......

原因是:java.security.PrivilegedActionException: com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 种IllegalAnnotationExceptionsITransferResult是一个接口,而JAXB无法处理接口。此问题与以下位置有关:在ITransferResult处。

我已经在SO上查找了答案,并应用了最常见的提示,但其中没有任何一种对我起作用。
我缺少什么?
2个回答

4
您可能需要在声明中将样式更改为DOCUMENT而不是RPC, 代码如下:@SOAPBinding(style = Style.RPC)。虽然这是一个旧问题,但我认为我可以回答它,因为人们经常遇到此类异常。在高级别上,两种样式的区别如下:Document:返回类型和方法参数在单独的XSD中清楚地解释,每种类型都有详细说明-有助于自定义数据类型(例如,在您的情况下是ITransferResult或java.util.List)。RPC:类型在WSDL本身中以简单的方式定义。

实际上,对我来说恰恰相反的帮助了。 我之前使用了@SOAPBinding,现在将其更改为@SOAPBinding(style = Style.RPC),所以问题已经解决 :) - Philipp Hellmayr

1
看起来它没有将 TransferResult 类上的注释处理为可绑定元素。这意味着您可能需要在接口 (ITransferResult) 上添加 @XmlSeeAlso(TransferResult.class)。您还需要在序列化实现 (TransferResult) 上放置 @XmlRootElement,以便可以生成实际的 XML 文档,而不仅仅是在其他文档中使用的类型。这是因为当 JAX-WS 实现创建其内部使用的 JAXB 上下文时,它仅使用您在服务接口上定义的参数和结果类型作为 JAXB.newInstance(…) 的参数;任何未列在其中(或通过 simple 遵循类型找到的)的内容都将被省略,而且使用的类型适配器可能不会处理注释(毕竟,它们不需要是它们正在适配的接口的实例,也不需要被适配的类型是一个接口)。
(是的,SOAP 响应是一个封闭文档,但推荐使用的方法是在 SOAP Body 中放置一个单独的元素,这意味着您需要知道该元素的 name。这意味着需要一个 @XmlRootElement 注释。)

警告:我不能保证这会百分之百地起作用。如果不行,你就必须转而使用具体类型(可能是简单的POJO)作为结果。这可能并不是一个特别令人愉快的事情,但至少很容易做到...


谢谢您的建议,不幸的是,它们都对我没有用。也许是我做错了什么。无论如何,正如您建议的那样,我放弃了接口的想法,开始使用简单的POJOs。还是非常感谢! - pizycki

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接