JAXB 编组对象时出现问题: javax.xml.bind.JAXBException: class ... 或其任何超类在此上下文中已知

发布于 2024-10-05 03:29:21 字数 2063 浏览 0 评论 0原文

在我的 JAX-RS 项目(泽西岛)中,我在将 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 工厂。

有什么想法吗?

In my JAX-RS project (Jersey) I'm having a problem getting one of the JAXB-annotated objects marshalled to JSON. Here is the error message I see in the logs:

SEVERE: Internal server error
javax.ws.rs.WebApplicationException: javax.xml.bind.JAXBException: class com.dnb.applications.webservice.mobile.view.CompaniesAndLocations nor any of its super class is known to this context.

Does this point to any specific problem? My resource has a method like this:

@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 is an empty interface. The above method returns an object of type CompaniesAndLocations, defined as follows:

@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 defines a number of other fields:

@XmlTransient
public abstract class BaseCompanies {

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

I should add that I'm deviating slightly from the approach used by other working code in the app. The other resource methods get their objects from an ObjectFactory that is annotated with @XmlRegistry. I don't think this is necessary, though. I have seen other code that directly instantiates the JAXB-annotated POJO'swithout using the ObjectFactory factory.

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

如歌彻婉言 2024-10-12 03:29:36

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

}

JAX-RS does what it can to bootstrap a JAXBContext, but it can't always reach all the classes it needs to know about. For this reason you can implement a ContextResolver. This gives you full control over how the JAXBContext is created. Below is an example of how it might look:

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

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文