【问题标题】:Problem with JAXB marshalling an object: javax.xml.bind.JAXBException: class ... or any of its super class is known to this contextJAXB 编组对象的问题:javax.xml.bind.JAXBException: class ... 或其任何超类在此上下文中是已知的
【发布时间】:2010-12-01 22:08:34
【问题描述】:

在我的 JAX-RS 项目 (Jersey) 中,我在将 JAXB 注释对象之一编组为 JSON 时遇到问题。这是我在日志中看到的错误消息:

严重:内部服务器错误 javax.ws.rs.WebApplicationException: javax.xml.bind.JAXBException: class com.dnb.applications.webservice.mobile.view.CompaniesAndLocations 及其任何超类对此上下文都是未知的。

这是否指向任何具体问题?我的资源有这样的方法:

@Path("/name/{companyname}/location/{location}")
@Produces("application/json; charset=UTF-8;")
@Consumes("application/json")
@POST
public Viewable findCompanyByCompanyNameAndLocationAsJSON(@PathParam("companyname") String companyName,
        @PathParam("location") String location, CriteriaView criteria) {
    criteria = criteria != null ? criteria : new CriteriaView();
    criteria.getKeywords().setCompanyName(companyName);
    return getCompanyListsHandler().listsByCompanyNameAndLocation(criteria, location);
}

Viewable 是一个空接口。上述方法返回一个CompaniesAndLocations类型的对象,定义如下:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "companiesAndLocations", propOrder = { "count", "normalizedLocations", "companyList", "companyMap", "modifiers",
        "modifiersMap", "companyCount", "navigators" })
public class CompaniesAndLocations extends BaseCompanies implements Viewable {

    @XmlElement(name = "normalizedLocations", required = false)
    protected List<NormalizedLocation> normalizedLocations;

    public List<NormalizedLocation> getNormalizedLocations() {
        if (normalizedLocations == null) {
            normalizedLocations = new ArrayList<NormalizedLocation>();
        }
        return normalizedLocations;
    }

}

BaseCompanies 定义了许多其他字段:

@XmlTransient
public abstract class BaseCompanies {

    @XmlElement(name = "modifiers", required = false)
    private List<Modifiers> modifiers;
....

我应该补充一点,我与应用程序中其他工作代码使用的方法略有不同。其他资源方法从带有 @XmlRegistry 注释的 ObjectFactory 中获取它们的对象。不过,我认为这没有必要。我见过其他代码直接实例化 JAXB 注释的 POJO,而不使用 ObjectFactory 工厂。

有什么想法吗?

【问题讨论】:

    标签: jaxb jax-rs


    【解决方案1】:

    JAX-RS 尽其所能引导 JAXBContext,但它并不总是能到达它需要知道的所有类。因此,您可以实现 ContextResolver。这使您可以完全控制如何创建 JAXBContext。下面是它的外观示例:

    package org.example.order;
    
    import javax.ws.rs.Produces;
    import javax.ws.rs.ext.ContextResolver;
    import javax.ws.rs.ext.Provider;
    import javax.xml.bind.JAXBContext;
    import javax.xml.transform.Source;
    import javax.xml.transform.stream.StreamSource;
    
    import org.eclipse.persistence.jaxb.JAXBContextFactory;
    
    @Provider
    @Produces({"application/xml", "application/json"})
    public class PurchaseOrderContextResolver implements ContextResolver<JAXBContext> {
    
        private JAXBContext jaxbContext;
    
        public PurchaseOrderContextResolver() {
            try {
                // Bootstrap your JAXBContext will all necessary classes
                jaxbContext = JAXBContext.newInstance(PurchaseOrder.class);
            } catch(Exception e) {
                throw new RuntimeException(e);
            }
        }
    
        public JAXBContext getContext(Class<?> clazz) {
            if(PurchaseOrder.class == clazz) {
                return jaxbContext;
            }
            return null;
        }
    
    }
    

    【讨论】:

    • 酷,谢谢,这看起来很有用。这本质上是 @XmlRegistry 注释在幕后所做的吗?
    • No @XmlRegistry 是别的东西。 ContextResolver 的目的是让开发人员完全控制 JAXBContext 的引导方式。如果没有它,JAX-RS 实现将从参数类型开始引导 JAXBContext,并遍历图以获取更多类型。通常这会得到你需要的一切,但是像继承和无类型列表这样的事情可能会导致类型被遗漏。 @XmlSeeAlso 注释也很有用。
    猜你喜欢
    • 2012-12-13
    • 2013-09-13
    • 2021-05-27
    • 2014-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-16
    • 1970-01-01
    相关资源
    最近更新 更多