2012-12-27 80 views
26

我想通過REST Web服務傳遞一個對象。以下是我的課程解釋我需要使用一些示例代碼的功能。javax.xml.bind.JAXBException:類***,也沒有任何它的超類已知此上下文

REST Web服務類方法

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

響應等級

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

系類

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

} 

當我在其他Web服務類中調用getDepartments方法時,它會返回以下異常。但是如果我改變對象有效負載部門在響應類它正確地返回json響應。但因爲我需要使用這個Response類來處理不同類型的類,所以我不能將有效載荷重新分配給一個類類型。任何人都可以在這件事情上幫助我嗎?

堆棧跟蹤

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 
+5

你應該接受提供的答案,因爲它工作得很好。 – Daniel

+0

@Shanaka接受提供的答案之一,#Bogdan答案相當不錯。選擇一個最佳答案,並幫助他人明智地選擇 – Jeevanantham

回答

49

JAX-RS實現自動支持類編組/解組基於發現JAXB註釋,而是因爲你的有效載荷被聲明爲Object,我想創建JAXBContext錯過了Department類當它是時間來組織它時,它不知道如何。

一個快速和骯髒的解決將是一個XmlSeeAlso註釋添加到您的響應類:

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

或一些更復雜的是用「豐富」的JAXB上下文的ResponseContextResolver

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); 
    } 
} 
+1

我有對象內的對象列表。通過'@ XmlSeeAlso'標籤解決。謝謝! – Daniel

+1

不適用於我:( – Anas

+0

當我使用XmlSeeAlso註釋它將此信息添加到節點:xmlns:xsi =「http://www.w3.org/2001/XMLSchema-instance」xsi:type =「my_class」 有沒有選擇刪除它? –

5

此異常可以通過指定全類路徑來解決。

例子:

,如果你被命名爲ExceptionDetails類。java的


傳遞參數迷途

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

權傳遞參數的方式

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

非常感謝, 帕塔

+7

只有在不同軟件包中有兩個不同版本的ExceptionDetails且導入語句使用「其他」軟件包時,指定軟件包纔會有所作爲? – DarthPablo

2

我有同樣的問題,我加入包探索到Jaxb2marshaller解決它。因爲春天將是這樣定義一個bean:

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

通過這種方式,如果所有的請求和響應類是不需要相同的包,具體說明在JAXBContext中

0

我有課使用JAXB參考實現和JBoss AS 7.1的類似問題。我能夠編寫一個確認JAXB在JBoss環境之外工作的集成測試(提示問題可能是JBoss中的類加載器)。

這是被賦予了錯誤(即不工作)代碼:

private static final JAXBContext JC; 

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

,這是工作的代碼(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); 
    } 
} 

在某些情況下,我得到了類,也沒有任何它的超類已知此上下文。在其他情況下,我還得到了org.foo.bar.ValueSet的異常,無法轉換爲org.foo.bar.ValueSet(類似於此處所述的問題:ClassCastException when casting to the same class)。

相關問題