JAXB编组对象的问题:javax.xml.bind.JAXBException:class ...或者它的任何超类都是这个上下文已知的

时间:2010-12-01 22:08:34

标签: jaxb jax-rs

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

  

严重:内部服务器错误   javax.ws.rs.WebApplicationException:javax.xml.bind.JAXBException:类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工厂。

有什么想法吗?

1 个答案:

答案 0 :(得分:7)

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

}