1

如何使一些 xjc 生成的类成为自定义异常的子类,以便您可以实际抛出它们,并由 JAXBContext 处理?通常 web 服务会返回定义的各种错误,这些错误确实应该是一个异常,但由于它们不是你需要不必要地包装它们。

4

2 回答 2

2

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

Java 模型 (Foo)

下面是一个简单的 Java 类,它扩展了Exception.

package forum12840627;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Foo extends Exception {

}

演示

下面的演示代码尝试JAXBContext在 Java 模型上创建一个。

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。我最初的可移植性问题可能不是什么大问题。

于 2012-12-05T14:21:08.710 回答
1

是的,我终于找到了一些东西!继承插件能够使生成的类从类继承或实现额外的接口。

你需要包括类似的东西

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

进入绑定文件并覆盖 getStackTrace() 以返回 null ,这样它就不会被编组。

Unfortunately you might run into trouble with some JAXB implementations (see Blaise Doughan's answer) - I haven't found a workaround for that yet. So you can either use a not quite nonportable solution, or wrap the JAXB objects into Exceptions.

于 2012-12-05T16:10:14.867 回答