I'm trying to pass a object via REST web service. Following are my classes explains the functionality that I need using some example codes.
Rest Web Service Class method
@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
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
@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. But If I change the type Object of the payload to Department in the Response class it returns the json response correctly. But since I need to use this Response class for different types of Classes I can't restring the payload to one class type. 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 createdJAXBContext
misses theDepartment
class and when it's time to marshall it it doesn't know how.A quick and dirty fix would be to add a
XmlSeeAlso
annotation to your response class:or something a little more complicated would be "to enrich" the JAXB context for the
Response
class by using aContextResolver
:I had faced the similar error when supporting one application. It was about the generated classes for a SOAP Webservice.
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 after which was generated by wsdl and xsd. after adding the jar with all the classes in the class path the issue was resolved.
This exception can be solved by specifying a full class path.
Example:
If you are using a class named
ExceptionDetails
Wrong Way of passing arguments
Right Way of passing arguments
I have the same problem and I solved it by adding package to explore to the Jaxb2marshaller. For spring will be define a bean like this:
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
I had a similar issue using the JAXB reference implementation and 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).
This is the code that was giving the error (i.e. not working):
and this is the code that worked (ValueSet is one of the classes marshaled from my XML).
In some cases I got the Class nor any of its super class is known to this context. 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).