如何使一些xjc生成的类成为自定义Exception的子类,这样你就可以实际抛出它们,并且可以通过JAXBContext进行处理?通常,webservices返回定义的各种故障,这些故障确实应该是一个例外,但是因为它们不是你需要不必要地包装它们。
答案 0 :(得分:2)
即使您可以创建一个从Exception
扩展的JAXB (JSR-222)模型,您也无法从中创建JAXBContext
。我建议将Exception
包装在与JAXB兼容的域模型中。
Java模型(Foo)
下面是一个扩展Exception
的简单Java类。
package forum12840627;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Foo extends Exception {
}
<强>演示强>
下面的演示代码尝试在Java模型上创建JAXBContext
。
package forum12840627;
import javax.xml.bind.JAXBContext;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Foo.class);
}
}
<强>输出强>
以下是运行演示代码返回的异常。问题是Exception
不是有效的JAXB类,而JAXB实现在处理Java模型时会引入超类。 (注意:在您自己的域模型中,您可以使用@XmlTransient
注释超级类以防止它们被处理:http://blog.bdoughan.com/2011/06/ignoring-inheritance-with-xmltransient.html)
Exception in thread "main" com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
java.lang.StackTraceElement does not have a no-arg default constructor.
this problem is related to the following location:
at java.lang.StackTraceElement
at public java.lang.StackTraceElement[] java.lang.Throwable.getStackTrace()
at java.lang.Throwable
at java.lang.Exception
at forum12840627.Foo
at com.sun.xml.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:102)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:472)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:302)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1140)
at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:154)
at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:121)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:202)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:363)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:574)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:522)
at forum12840627.Demo.main(Demo.java:8)
更新#1
如果您使用EclipseLink JAXB(MOXy)作为JAXB提供程序,那么您将看不到此异常,因为javax.*
和java.*
包中的类不被视为域类。 MOXy是WebLogic 12c环境中的默认JAXB提供程序,或者可以使用jaxb.properties
文件进行配置。
了解更多信息
更新#2
最新版本的JAXB参考实现似乎现在处理这个用例以及MOXy。我原来的可移植性问题可能不是一个问题。
答案 1 :(得分:1)
您需要包含类似
的内容 <bindings node="//xsd:complexType[@name='WhateverException']">
<inheritance:extends>foo.bar.WhateverException</inheritance:extends>
</bindings>
进入绑定文件并覆盖getStackTrace()以返回null,以便它不会被编组。
不幸的是,您可能会遇到一些JAXB实现的问题(请参阅Blaise Doughan's answer) - 我还没有找到解决方法。因此,您可以使用不太不可移植的解决方案,也可以将JAXB对象包装到Exceptions中。