【问题标题】:How to marshal a subclass of exception using JAXB如何使用 JAXB 编组异常的子类
【发布时间】:2014-07-24 21:22:26
【问题描述】:

我发现了几个类似的问题,但所提出的解决方案都不适合我。经过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>

我没弄明白怎么回事。感谢您的帮助。

【问题讨论】:

  • 所以您正在接收 Web 服务响应(可能是 SOAP 消息),将这些响应解组为 Java 对象,然后(重新)编组回 XML?
  • unmashall to java 部分由 cxf 完成,对我来说是透明的。我使用 cxf 生成 Web 服务类,然后使用这些类进行查询,并得到 java 对象作为回报

标签: java xml exception jaxb marshalling


【解决方案1】:

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

异常类

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();
    }
    
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多