Java JAXB 无法处理接口 - 我错过了什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23196624/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JAXB cannot handle an interface - what am I missing?
提问by pizycki
I'm getting familiar with web services in Java using Jax-ws (or JAXB, not sure, anyway...).
我正在使用 Jax-ws(或 JAXB,不确定,无论如何......)熟悉 Java 中的 Web 服务。
I've created small project with a single webservice. The WS has the only endpoint called transfer and returns objects inheriting ITransferResult interface.
我用一个网络服务创建了一个小项目。WS 具有唯一的称为 transfer 的端点,并返回继承 ITransferResult 接口的对象。
Web service contract
网络服务合同
//Service Endpoint Interface
@WebService
@SOAPBinding(style = Style.RPC)
public interface IBankWebSrv {
@WebMethod
ITransferResult transfer(String accountNumber, double amount);
}
Web service implementation
网络服务实现
//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;
}
}
TransferResult contract
TransferResult 合约
@XmlJavaTypeAdapter(TransferResult.class)
public interface ITransferResult {
boolean isSuccessful();
void setSuccessful(boolean successful);
}
TransferResult implementation
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;
}
}
When I publish my web service, I get the following error:
当我发布 Web 服务时,出现以下错误:
Exception in thread "main" javax.xml.ws.WebServiceException: Unable to create JAXBContext...
Caused by: java.security.PrivilegedActionException: com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions ITransferResult is an interface, and JAXB can't handle interfaces.this problem is related to the following location: at ITransferResult
线程“main”中的异常 javax.xml.ws.WebServiceException:无法创建 JAXBContext...
引起:java.security.PrivilegedActionException: com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions ITransferResult 是一个接口,JAXB 不能处理接口。此问题与以下位置有关:在 ITransferResult
I've looked over SO for the answer and applied to the most repetitive tips, but none of them have worked for me yet.
我已经查看了 SO 的答案并应用于最重复的提示,但没有一个对我有用。
What am I missing?
我错过了什么?
采纳答案by Donal Fellows
It looks like it's not processing the annotations on the TransferResult
class as a bindable element. That means you probably need to add @XmlSeeAlso(TransferResult.class)
to the interface (ITransferResult
). You also need to put @XmlRootElement
on the serialization-implementation (TransferResult
) so that an actual XML document can be produced, and not just a type that you use in some other document. This is because when the JAX-WS implementation is creating the JAXB context that it uses internally, it only uses the argument and result types that you define on the service interface as arguments to JAXB.newInstance(…)
; anything not literally listed there (or findable via simplefollowing the types) will be omitted, and it's entirely possible that the type adapters used are not processed for annotations (after all, they don't need to be instances of the interface they're adapting, nor does the type being adapted need to be an interface).
看起来它没有将TransferResult
类上的注释作为可绑定元素进行处理。这意味着您可能需要添加@XmlSeeAlso(TransferResult.class)
到接口 ( ITransferResult
)。您还需要@XmlRootElement
使用序列化实现 ( TransferResult
) 以便可以生成实际的 XML 文档,而不仅仅是您在其他文档中使用的类型。这是因为当 JAX-WS 实现创建它在内部使用的 JAXB 上下文时,它只使用您在服务接口上定义的参数和结果类型作为参数JAXB.newInstance(…)
;任何没有在那里列出的东西(或者可以通过简单的方式找到后面的类型)将被省略,并且完全有可能不处理所使用的类型适配器以进行注释(毕竟,它们不需要是它们正在适应的接口的实例,也不需要被适应的类型成为一个接口)。
(Yes, a SOAP response is an enclosing document, but the recommended way of using it is to put a single element inside the SOAP Body
, and that means you need to know the name
of the element. Which means an @XmlRootElement
annotation.)
(是的,SOAP 响应是一个封闭文档,但推荐的使用方法是将单个元素放入 SOAP 中Body
,这意味着您需要知道name
元素的 。这意味着@XmlRootElement
注释。)
Warning: I'm not 100% sure that this will work. If it doesn't, you'll have to switch to using concrete types (probably straight POJOs) as results. It might not be a particularly palatable thing, but it's at least easy to do…
警告:我不是 100% 确定这会起作用。如果没有,您将不得不切换到使用具体类型(可能是直接的 POJO)作为结果。这可能不是什么特别可口的事情,但至少很容易做到……
回答by Santosh Kumar Arjunan
You may need to change the style to be DOCUMENTinstead of RPCin your declaration at @SOAPBinding(style = Style.RPC)
您可能需要在声明中将样式更改为DOCUMENT而不是RPC@SOAPBinding(style = Style.RPC)
Although this is an old question, I thought I'd answer it as it's common exception people encounter.
虽然这是一个老问题,但我想我会回答它,因为这是人们遇到的常见例外。
The difference between the two styles in high level is as follows
两种风格在高层的区别如下
Document: The return type and method arguments are clearly explained in a separate XSD with each type in detail - helpful in case of custom data types (Example in your case
ITransferResult
orjava.util.List
).RPC: the types are defined in the WSDL itself in simple manner.
文档:返回类型和方法参数在单独的 XSD 中清楚地解释了每种类型的详细信息 - 在自定义数据类型的情况下很有帮助(例如您的情况
ITransferResult
或java.util.List
)。RPC:类型以简单的方式在 WSDL 本身中定义。