如何使用JAXB编组异常的子类

时间:2014-06-04 09:31:37

标签: java xml exception jaxb marshalling

我发现了几个类似的问题,但没有提出的解决方案对我有用。经过2天的搜索,我决定发布我的问题,对不起它很长,请你好。

问题

在我的应用程序中,我从Java获取Web服务的响应,并且我使用JAXB编写这些响应来获取xml文件。当没有异常上升时,一切都很好。但问题是当我捕获异常时,我无法将它们序列化为xml。

我无法在我的类中添加注释(因为它们是使用cxf自动生成的)。

我的代码

编组方法代码

public static <T> void java2Xml(T objectToSerialize) {
    Class<?> c = objectToSerialize.getClass();
    try {
        JAXBContext jaxbContext = JAXBContext.newInstance(c);
        @SuppressWarnings({ "unchecked", "rawtypes" })
        JAXBElement<T> je2 = new JAXBElement(new QName(c.getSimpleName()), c, objectToSerialize);
        Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
        jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        // TODO write the result in a file
        jaxbMarshaller.marshal(je2, System.out);
    } catch (JAXBException e) {
        e.printStackTrace();
    }
}

例外类的样本

  package com.adonis.pidi.wsdl.transfert;
  import javax.xml.ws.WebFault;
  /**
   * This class was generated by Apache CXF 2.7.1
   * 2014-06-03T11:21:39.951+02:00
   * Generated source version: 2.7.1
   */

  @WebFault(name = "WSErreurFonctionnelle", targetNamespace = "urn:pidi.adonis.com:wsdl:exception")
  public class WSErreurFonctionnelle extends Exception {

    private com.adonis.pidi.wsdl.exception.WSErreurFonctionnelle wsErreurFonctionnelle;
    public WSErreurFonctionnelle() {
        super();
    }
    public WSErreurFonctionnelle(String message) {
        super(message);
    }

    public WSErreurFonctionnelle(String message, Throwable cause) {
        super(message, cause);
    }
    public WSErreurFonctionnelle(String message, com.adonis.pidi.wsdl.exception.WSErreurFonctionnelle wsErreurFonctionnelle) {
        super(message);
        this.wsErreurFonctionnelle = wsErreurFonctionnelle;
    }
    public WSErreurFonctionnelle(String message, com.adonis.pidi.wsdl.exception.WSErreurFonctionnelle wsErreurFonctionnelle, Throwable cause) {
        super(message, cause);
        this.wsErreurFonctionnelle = wsErreurFonctionnelle;
    }
    public com.adonis.pidi.wsdl.exception.WSErreurFonctionnelle getFaultInfo() {
        return this.wsErreurFonctionnelle;
    }
}

预期结果

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<WSErreurFonctionnelle xmlns:ns2="urn:pidi.adonis.com:wsdl:exception">
    <ns2:WSErreurFonctionnelle>
        <ns2:erreurs>
            <ns2:codeErreur>10</ns2:codeErreur>
            <ns2:libelleErreur>patati patata</ns2:libelleErreur>
        </ns2:erreurs>
        <ns2:erreurs>
            <ns2:codeErreur>133</ns2:codeErreur>
            <ns2:libelleErreur>bla bla bla
            </ns2:libelleErreur>
        </ns2:erreurs>
    </ns2:WSErreurFonctionnelle>
</WSErreurFonctionnelle>

实际结果 我得到了一个例外

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<WSErreurFonctionnelle>
    <stackTrace/>
    <stackTrace/>
    <stackTrace/>
    <stackTrace/>
    <stackTrace/>
</WSErreurFonctionnelle>

环境

Java 6

maven依赖项:

<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
    <version>2.2.7</version>
</dependency>
<dependency>
    <groupId>javax.xml.ws</groupId>
    <artifactId>jaxws-api</artifactId>
    <version>2.1</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>com.sun.xml.ws</groupId>
    <artifactId>jaxws-rt</artifactId>
    <version>2.1.4</version>
    <scope>runtime</scope>
</dependency>

我没有弄错。谢谢你的帮助。

1 个答案:

答案 0 :(得分:0)

我有同样的问题,我正在为异常类使用包装器,如下所示:

ExceptionClass

import lombok.Getter;
import lombok.Setter;

public class EntityObjectNotFoundException extends Exception {
    private static final long serialVersionUID = 1L;
    
    @Getter @Setter
    private Class<? extends EntityIntf> entityClass;
    @Getter @Setter
    private Integer id;
    
    public EntityObjectNotFoundException(Class<? extends EntityIntf> entityClass, Integer id) {
        super(String.format("Entity class \"%s\" not found by ID#%d", entityClass.getSimpleName(), id));
        
        this.entityClass = entityClass;
        this.id = id;
    }
}

包装器类

@XmlRootElement(name="EntityObjectNotFoundException")
@XmlType(propOrder={"message","id","entityClass"})
@XmlAccessorType(XmlAccessType.PROPERTY)
@NoArgsConstructor
public class EntityObjectNotFoundExceptionWrapper {
    private EntityObjectNotFoundException e;
    
    EntityObjectNotFoundExceptionWrapper(EntityObjectNotFoundException e) {
        this.e = e;
    }
    
    public String getMessage() {
        return e.getMessage();
    }
    
    public void setMessage(String message) {
    }
    
    public Integer getId() {
        return e.getId();
    }
    
    public void setId(Integer id) {
    }
    
    public String getEntityClass() {
        return e.getEntityClass().getSimpleName();
    }
    
    @XmlElement(name="entity_class")
    public void setEntityClass(String clazz) {
    }
}

XML结果输出

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<EntityObjectNotFoundException>
    <message>Entity class "CityEntity" not found by ID#111</message>
    <id>111</id>
    <entity_class>CityEntity</entity_class>
</EntityObjectNotFoundException>

(由JAX-RS封送)

import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.ExceptionMapper;

public class EntityObjectNotFoundExceptionMapper implements ExceptionMapper<EntityObjectNotFoundException> {

    @Override
    public Response toResponse(EntityObjectNotFoundException e) {
        return Response.status(Status.BAD_REQUEST).entity(new EntityObjectNotFoundExceptionWrapper(e)).build();
    }
    
}