2012-10-11 28 views
1

如何才能创建自定义异常的一些xjc生成类的子类,以便您可以实际抛出它们,并且可以通过JAXBContext来处理?通常,web服务返回定义的各种故障,这些故障实际上应该是一个例外,但由于它们不是你需要不必要地包装它们。Jaxb Xjc:使异常的生成类子类型?

回答

1

是的,我终于找到了一些东西! Inheritance plugin能够使生成的类从类继承或实现其他接口。

您需要包括像

<bindings node="//xsd:complexType[@name='WhateverException']"> 
    <inheritance:extends>foo.bar.WhateverException</inheritance:extends> 
    </bindings> 

到绑定文件并覆盖的getStackTrace()返回空值,使得它不会整理。

不幸的是,您可能会遇到一些JAXB实现问题(请参阅Blaise Doughan's answer) - 我还没有找到解决方法。因此,您可以使用一个不太重要的解决方案,或者将JAXB对象包装为Exceptions。

2

即使您可以创建一个从Exception扩展的JAXB (JSR-222)模型,您也无法从中创建JAXBContext。我建议将Exception包装在与JAXB兼容的域模型中。

Java模型(美孚)

下面是扩展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一样处理这个用例。我原来的可移植性问题可能不是一个问题。

+0

感谢您的回答!您对普通的JDK6是正确的。在我们的项目中奇怪的是JAXBContext.newInstance没有抛出(可能是因为我们包含了一些XML库)。因此,在我们的设置中,您可以重写getStackTrace()以返回null,然后您可以成功编组和解组异常。 (也许人们也可以为StacktraceElement编写一个XmlAdapter,以避免在普通JDK6上出现这个问题。)所以问题仍然是如何使xjc子类成为自定义的异常类型。 –

+0

@hstoerr - 您可能正在使用MOXy作为您的JAXB提供程序(请参阅我的更新)。 –

+0

对于我目前的JAXB提供者来说,它无论如何都可以工作,但我毫不犹豫地使用了一个不可移植的解决方案。您是否看到了将XmlAdapter配置为StacktraceElement(应该被忽略)或其他方法来避免普通JDK6上出现此问题的方法?我没有管理。 :-( –

相关问题