JAXB编组对象时出现问题:javax.xml.bind.JAXBException:class。。。或者它的任何一个超类在此上下文中都是已知的

JAXB编组对象时出现问题:javax.xml.bind.JAXBException:class。。。或者它的任何一个超类在此上下文中都是已知的,jaxb,jax-rs,Jaxb,Jax Rs,在我的JAX-RS项目(Jersey)中,我在将一个JAXB注释对象编组为JSON时遇到问题。以下是我在日志中看到的错误消息: 严重:内部服务器错误 javax.ws.rs.WebApplicationException:javax.xml.bind.jaxbeexception:class com.dnb.applications.webservice.mobile.view.CompaniesAndLocations及其任何超类在此上下文中都是未知的 这是否指向任何特定的问题?我的资源有这样

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

严重:内部服务器错误 javax.ws.rs.WebApplicationException:javax.xml.bind.jaxbeexception: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);
}
可查看
是一个空界面。上述方法返回类型为
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;
    }

}
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name=“companiesAndLocations”,proporter={“count”,“normalizedLocations”,“companyList”,“companyMap”,“modifiers”,
“修改器映射”、“公司计数”、“导航器”})
公共类公司和地点扩展基本公司实现可查看{
@XmlElement(name=“normalizedLocations”,必需=false)
受保护的位置列表;
公共列表getNormalizedLocations(){
if(normalizedLocations==null){
normalizedLocations=新的ArrayList();
}
返回标准化位置;
}
}
BaseCompanies定义了许多其他字段:

@XmlTransient
public abstract class BaseCompanies {

    @XmlElement(name = "modifiers", required = false)
    private List<Modifiers> modifiers;
....
@xmltransive
公共抽象类公司{
@XmlElement(name=“modifiers”,必需=false)
私有列表修饰符;
....
我应该补充一点,我与应用程序中其他工作代码使用的方法略有不同。其他资源方法从使用
@XmlRegistry
注释的ObjectFactory获取其对象。不过,我认为这不是必要的。我见过其他代码直接实例化JAXB注释的POJO'swithoutg对象工厂


有什么想法吗?

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

}
package org.example.order;
导入javax.ws.rs.products;
导入javax.ws.rs.ext.ContextResolver;
导入javax.ws.rs.ext.Provider;
导入javax.xml.bind.JAXBContext;
导入javax.xml.transform.Source;
导入javax.xml.transform.stream.StreamSource;
导入org.eclipse.persistence.jaxb.JAXBContextFactory;
@提供者
@产生({“application/xml”、“application/json”})
公共类PurchaseOrderContextResolver实现ContextResolver{
私有JAXBContext JAXBContext;
public PurchaseOrderContextResolver(){
试一试{
//引导您的JAXBContext将包含所有必要的类
jaxbContext=jaxbContext.newInstance(PurchaseOrder.class);
}捕获(例外e){
抛出新的运行时异常(e);
}
}
公共JAXBContext getContext(类clazz){
if(PurchaseOrder.class==clazz){
返回jaxbContext;
}
返回null;
}
}

Cool,谢谢,这看起来很有用。@XmlRegistry注释本质上就是这么做的吗?@XmlRegistry不是别的。ContextResolver的目的是让开发人员完全控制如何引导JAXBContext。没有它,JAX-RS实现将从参数类型,并遍历图形,拉入更多类型。通常情况下,这会获得您需要的所有信息,但继承和未类型化列表等内容可能会导致类型丢失。@XmlSeeAllow注释也很有用。