简体   繁体   English

javax.xml.bind.JAXBException: Class *** 它的任何超级 class 在此上下文中都是已知的

[英]javax.xml.bind.JAXBException: Class *** nor any of its super class is known to this context

I'm trying to pass a object via REST web service.我正在尝试通过 REST web 服务传递 object。 Following are my classes explains the functionality that I need using some example codes.以下是我的课程,使用一些示例代码解释了我需要的功能。

Rest Web Service Class method Rest Web 服务 Class 方法

@POST
@Path("/find")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces({MediaType.APPLICATION_JSON})
public Response getDepartments(){
    Response response = new Response();

    try {

        response.setCode(MessageCode.SUCCESS);
        response.setMessage("Department Names");
        Department dept = new Department("12", "Financial");
        response.setPayload(dept);

    } catch (Exception e) {
        response.setCode(MessageCode.ERROR);
        response.setMessage(e.getMessage());
        e.printStackTrace();
    }       
    return response;
}

Response Class响应 Class

import java.io.Serializable;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement

public class Response implements Serializable{

    private static final long serialVersionUID = 1L;

    public enum MessageCode {
        SUCCESS, ERROR, UNKNOWN
    }

    private MessageCode code;
    private String message;
    private Object payload;

    public MessageCode getCode() {
        return code;
    }

    public void setCode(MessageCode code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Object getPayload() {
        return payload;
    }

    public void setPayload(Object payload) {
        this.payload = payload;
    }
}

Department Class部门 Class

@XmlRootElement
public class Department implements java.io.Serializable {


    private String deptNo;
    private String deptName;


    public Department() {
    }

    public Department(String deptNo, String deptName) {
        this.deptNo = deptNo;
        this.deptName = deptName;
    }

    public String getDeptNo() {
        return this.deptNo;
    }

    public void setDeptNo(String deptNo) {
        this.deptNo = deptNo;
    }

    public String getDeptName() {
        return this.deptName;
    }

    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }

}

When I make a call to getDepartments method in the rest web service class it returns following exceptions.当我在 rest web 服务 class 中调用 getDepartments 方法时,它返回以下异常。 But If I change the type Object of the payload to Department in the Response class it returns the json response correctly.但是,如果我在响应 class 中将负载的类型Object更改为部门,它会正确返回 json 响应。 But since I need to use this Response class for different types of Classes I can't restring the payload to one class type.但是由于我需要将此 Response class 用于不同类型的类,因此我无法将有效负载重新串成一种 class 类型。 Can anyone please help me in this matter?谁能帮我解决这个问题?

Stack Trace堆栈跟踪

Dec 27, 2012 9:34:18 PM com.sun.jersey.spi.container.ContainerResponse logException
SEVERE: Mapped exception to response: 500 (Internal Server Error)
javax.ws.rs.WebApplicationException: javax.xml.bind.MarshalException
 - with linked exception:
[javax.xml.bind.JAXBException: class Department nor any of its super class is known to this context.]
    at com.sun.jersey.core.provider.jaxb.AbstractRootElementProvider.writeTo(AbstractRootElementProvider.java:159)
    at com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:306)
    at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1437)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339)
    at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:401)
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:766)
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:450)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.Server.handle(Server.java:326)
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
    at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:945)
    at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:756)
    at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
    at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:410)
    at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
Caused by: javax.xml.bind.MarshalException
 - with linked exception:
[javax.xml.bind.JAXBException: class Department nor any of its super class is known to this context.]
    at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:323)
    at com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:177)
    at com.sun.jersey.json.impl.BaseJSONMarshaller.marshallToJSON(BaseJSONMarshaller.java:103)
    at com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider.writeTo(JSONRootElementProvider.java:136)
    at com.sun.jersey.core.provider.jaxb.AbstractRootElementProvider.writeTo(AbstractRootElementProvider.java:157)
    ... 23 more
Caused by: javax.xml.bind.JAXBException: class Department nor any of its super class is known to this context.
    at com.sun.xml.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:250)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:265)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:657)
    at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:156)
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:344)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsSoleContent(XMLSerializer.java:597)
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(ClassBeanInfoImpl.java:328)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:498)
    at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:320)
    ... 27 more
Caused by: javax.xml.bind.JAXBException: class Department nor any of its super class is known to this context.
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getBeanInfo(JAXBContextImpl.java:611)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:652)
    ... 33 more

JAX-RS implementations automatically support marshalling/unmarshalling of classes based on discoverable JAXB annotations, but because your payload is declared as Object , I think the created JAXBContext misses the Department class and when it's time to marshall it it doesn't know how. JAX-RS 实现自动支持基于可发现的 JAXB 注释的类的编组/解组,但是因为您的有效负载被声明为Object ,我认为创建的JAXBContext错过了Department类,并且当需要编组它时它不知道如何。

A quick and dirty fix would be to add a XmlSeeAlso annotation to your response class:一个快速而肮脏的解决方法是在你的响应类中添加一个XmlSeeAlso注释:

@XmlRootElement
@XmlSeeAlso({Department.class})
public class Response implements Serializable {
  ....

or something a little more complicated would be "to enrich" the JAXB context for the Response class by using a ContextResolver :或者更复杂的事情是通过使用ContextResolver来“丰富” Response类的 JAXB 上下文:

import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;

@Provider
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public class ResponseResolver implements ContextResolver<JAXBContext> {
    private JAXBContext ctx;

    public ResponseResolver() {
        try {
            this.ctx = JAXBContext.newInstance(

                        Response.class, 
                        Department.class

                    );
        } catch (JAXBException ex) {
            throw new RuntimeException(ex);
        }
    }

    public JAXBContext getContext(Class<?> type) {
        return (type.equals(Response.class) ? ctx : null);
    }
}

I have the same problem and I solved it by adding package to explore to the Jaxb2marshaller.我有同样的问题,我通过向 Jaxb2marshaller 添加要探索的包来解决它。 For spring will be define a bean like this:对于 spring 将定义一个这样的 bean:

@Bean
    public Jaxb2Marshaller marshaller() {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        String[] packagesToScan= {"<packcge which contain the department class>"};
        marshaller.setPackagesToScan(packagesToScan);
        return marshaller;
    }

By this way if all your request and response classes are in the same package you do not need to specifically indicate the classes on the JAXBcontext通过这种方式,如果您所有的请求和响应类都在同一个包中,您就不需要在 JAXBcontext 上特别指明这些类

This exception can be solved by specifying a full class path.可以通过指定完整的类路径来解决此异常。

Example:例子:

If you are using a class named ExceptionDetails如果您正在使用名为ExceptionDetails的类


Wrong Way of passing arguments传递参数的错误方式

JAXBContext jaxbContext = JAXBContext.newInstance(ExceptionDetails.class);

Right Way of passing arguments传递参数的正确方式

JAXBContext jaxbContext = JAXBContext.newInstance(com.tibco.schemas.exception.ExceptionDetails.class);

I had a similar issue using the JAXB reference implementation and JBoss AS 7.1.我在使用 JAXB 参考实现和 JBoss AS 7.1 时遇到了类似的问题。 I was able to write an integration test that confirmed JAXB worked outside of the JBoss environment (suggesting the problem might be the class loader in JBoss).我能够编写一个集成测试,确认 JAXB 在 JBoss 环境之外工作(表明问题可能出在 JBoss 中的类加载器)。

This is the code that was giving the error (ie not working):这是给出错误的代码(即不工作):

private static final JAXBContext JC;

static {
    try {
        JC = JAXBContext.newInstance("org.foo.bar");
    } catch (Exception exp) {
        throw new RuntimeException(exp);
    }
}

and this is the code that worked (ValueSet is one of the classes marshaled from my XML).这是有效的代码(ValueSet 是从我的 XML 编组的类之一)。

private static final JAXBContext JC;

static {
    try {
        ClassLoader classLoader = ValueSet.class.getClassLoader();
        JC = JAXBContext.newInstance("org.foo.bar", classLoader);
    } catch (Exception exp) {
        throw new RuntimeException(exp);
    }
}

In some cases I got the Class nor any of its super class is known to this context.在某些情况下,我得到了 Class 或其任何超类在此上下文中都是已知的。 In other cases I also got an exception of org.foo.bar.ValueSet cannot be cast to org.foo.bar.ValueSet (similar to the issue described here: ClassCastException when casting to the same class ).在其他情况下,我也遇到了 org.foo.bar.ValueSet cannot be cast to org.foo.bar.ValueSet 的异常(类似于此处描述的问题: ClassCastException when cast to the same class )。

I had faced the similar error when supporting one application.我在支持一个应用程序时遇到了类似的错误。 It was about the generated classes for a SOAP Webservice.它是关于为 SOAP Web 服务生成的类。

The issue was caused due to the missing classes.该问题是由于缺少类引起的。 When javax.xml.bind.Marshaller was trying to marshal the jaxb object it was not finding all dependent classes which were generated by using wsdl and xsd.当 javax.xml.bind.Marshaller 试图编组 jaxb 对象时,它没有找到所有使用 wsdl 和 xsd 生成的依赖类。 after adding the jar with all the classes at the class path the issue was resolved.在类路径中添加包含所有类的 jar 后,问题得到解决。

Ftrujillo's answer works well but if you only have one package to scan this is the shortest form:: Ftrujillo 的答案很有效,但如果您只有一个包裹要扫描,这是最短的形式:

    @Bean
    public Jaxb2Marshaller marshaller() {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        marshaller.setContextPath("your.package.to.scan");
        return marshaller;
    }

This errors occurs when we use same method name for Jaxb2Marshaller for exemple:例如,当我们为 Jaxb2Marshaller 使用相同的方法名称时会发生此错误:

    @Bean
    public Jaxb2Marshaller marshallerClient() {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        // this package must match the package in the <generatePackage> specified in
        // pom.xml
        marshaller.setContextPath("library.io.github.walterwhites.loans");

        return marshaller;
    }

And on other file和其他文件

    @Bean
    public Jaxb2Marshaller marshallerClient() {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        // this package must match the package in the <generatePackage> specified in
        // pom.xml
        marshaller.setContextPath("library.io.github.walterwhites.client");

        return marshaller;
    }

Even It's different class, you should named them differently即使是不同的类,你也应该以不同的方式命名它们

In addition to defining the packags to scan, we must also ensure that we have @XmlRootElement annotation on top of the class we are trying to unmarshal/marshal.除了定义要扫描的包之外,我们还必须确保在我们尝试解组/编组的 class 之上有@XmlRootElement注释。

Example:例子:

@Bean
public Jaxb2Marshaller jaxb2Marshaller() {
    var jaxb2Marshaller = new Jaxb2Marshaller();
    jaxb2Marshaller.setPackagesToScan("com.yourpackages");

    return jaxb2Marshaller;
}

@Data
@XmlRootElement
public class ValueIndividual{
    private String id;
    private Member member;
    private UserDate updated;
    private String language_v;
}

Like already proposed by @ftrujillo if you use the Spring Jaxb2Marshaller, you can set the packages to scan.就像@ftrujillo 已经提出的那样,如果您使用 Spring Jaxb2Marshaller,您可以将包设置为扫描。 In some cases, if there is a more sophisticated XSD model with inheritance or have just more wide spread model, there could be a problem to get the information in the class hierarchy which packages to scan, then you can use the scan of the object hierarchy.在某些情况下,如果有更复杂的带有继承的 XSD 模型或者只是具有更广泛传播的模型,那么在类层次结构中获取要扫描的包的信息可能会出现问题,那么您可以使用对象层次结构的扫描. In such case I took the advantage of the following function, handling the plain POJO hierarchy (I believe it could be possibly enhanced for non-simple POJO):在这种情况下,我利用了以下功能,处理普通 POJO 层次结构(我相信它可能会针对非简单 POJO 进行增强):

....
            Jaxb2Marshaller locMarshaller = new Jaxb2Marshaller();
            locMarshaller.setPackagesToScan(
                    resolveJaxb2MarshallerPackagesToScan(
                            someFaultContentContainerClass,
                            someFaultContentClass
                    )
            );
...

    /**
     * Resolves the packages which have to be passed into the Spring Jaxb2Marshaller
     * to be able to perform the serialization/deserialization action
     * @param aClassesToBeMarshalled classes which has to be marshalled. Null array items
     *   are ignored without any error.
     * @return packages which have to be scanned by Spring Jaxb2Marshaller for it.
     */
    public static String[] resolveJaxb2MarshallerPackagesToScan(Class<?>... aClassesToBeMarshalled) {
        List<String> locResultList = new ArrayList<>();
        for (Class<?> locProcessedTopLevelClass : aClassesToBeMarshalled) {
            Class<?> locProcessedClass = locProcessedTopLevelClass;
            while (locProcessedClass != null) {
                if (!locResultList.contains(locProcessedClass.getPackageName()))
                    locResultList.add(locProcessedClass.getPackageName());
                locProcessedClass = locProcessedClass.getSuperclass();
            }
        }
        return locResultList.toArray(new String[0]);
    }


I know that it's an old question, but you can change the Response using a parameter (P):我知道这是一个老问题,但您可以使用参数 (P) 更改响应:

public class Response<P> implements Serializable{

private static final long serialVersionUID = 1L;

public enum MessageCode {
    SUCCESS, ERROR, UNKNOWN
}

private MessageCode code;
private String message;
private P payload;

...
public P getPayload() {
    return payload;
}

public void setPayload(P payload) {
    this.payload = payload;
}

} }

The method would be方法是

public Response<Departments> getDepartments(){...}

I can't try it now but it should works.我现在无法尝试,但它应该有效。

Otherwise it's possible to extends Response否则可以扩展响应

@XmlRootElement    
public class DepResponse extends Response<Department> {<no content>}

I had a similar error, same error message but different cause.我有一个类似的错误,相同的错误信息但不同的原因。

In my case the problem was an incomplete ObjectFactory implementation which was automatically created empty.在我的情况下,问题是一个不完整的 ObjectFactory 实现,它被自动创建为空。 After coding the ObjectFactory for my main class the problem was solved.在为我的主类编写 ObjectFactory 后,问题就解决了。

@XmlRegistry
public class ObjectFactory {

    /**
     * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: x
     * 
     */
    public ObjectFactory() {
    }

    public CartaPorte createCartaPorte() {
        return new CartaPorte();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 由以下原因引起:javax.xml.bind.JAXBException:该上下文不知道此类或其任何超类 - Caused by: javax.xml.bind.JAXBException: class nor any of its super class is known to this context 编组错误:javax.xml.bind.JAXBException:此上下文已知类或其任何超类 - Marshalling error: javax.xml.bind.JAXBException: class nor any of its super class is known to this context javax.xml.bind.JAXBException:class <ClassName> 在这种情况下,也不知道它的任何超类 - javax.xml.bind.JAXBException: class <ClassName> nor any of its super class is known to this context 线程“主”中的异常javax.xml.bind.JAXBException:此上下文已知类或其任何超类 - Exception in thread “main” javax.xml.bind.JAXBException: class nor any of its super class is known to this context javax.xml.bind.MarshalException-带有链接的异常:[javax.xml.bind.JAXBException:class **或其任何超类对此上下文都是已知的 - javax.xml.bind.MarshalException - with linked exception: [javax.xml.bind.JAXBException: class ** nor any of its super class is known to this context JAXB ANY 元素添加编组错误 javax.xml.bind.JAXBException: class *** 或其任何超类在此上下文中都是已知的 - JAXB ANY element add marhalling error javax.xml.bind.JAXBException: class *** nor any of its super class is known to this context javax.xml.bind.JAXBException: class java.util.ArrayList nor any of its super class is known to this context - javax.xml.bind.JAXBException: class java.util.ArrayList nor any of its super class is known to this context JAXBException: SaveButton 或其任何超类在此上下文中都是已知的 - JAXBException: SaveButton nor any of its super class is known to this context JAXBException UnmarshallerImpl或其任何超类对此上下文都是已知的 - JAXBException UnmarshallerImpl nor any of its super class is known to this context 此上下文已知javax.xml.bind.MarshalException或其任何超类 - javax.xml.bind.MarshalException nor any of its super class is known to this context
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM