cxf 结合 spring 发布web service时 不能实例化User对象的问题

在service层中调用了Dao方法来进行数据库的操作 然后又重新了UserWebservice接口及其实现类 在实现类中直接调用service的方法
domain中
User类

public abstract class User {
private String userName;
private String userPassword;
private String mobile;
private String email;
private String nickname;
private String region;
private java.util.Date birthday ;
private String telephone;
private String address;
private String postcode;
private String signature;
private String imageUrl;
private int userID;
private Set rightSet = new HashSet();
//getter 和setter略

@Override
public String toString() {
    return "User [userName=" + userName + ", userPassword=" + userPassword
            + ", mobile=" + mobile + ", email=" + email + ", nickname="
            + nickname + ", region=" + region + ", birthday=" + birthday
            + ", telephone=" + telephone + ", address=" + address
            + ", postcode=" + postcode + ", signature=" + signature
            + ", imageUrl=" + imageUrl + ", userID=" + userID
            + ", rightSet=" + rightSet.size() + "]";
}

}

[code="java"]
public class Member extends User {

@Override
public boolean getIsAdmin() {
    // TODO Auto-generated method stub
    return false;
}

}
[/code]
[code="java"]
public class Admin extends User {

@Override
public boolean getIsAdmin() {
    // TODO Auto-generated method stub
    return true;
}

}
[/code]

Right类
[code="java"]
public class Right {
private int rightID;
private String name;
private Set userSet = new HashSet();

public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public int getRightID() {
    return rightID;
}
public void setRightID(int rightID) {
    this.rightID = rightID;
}



public Set<User> getUserSet() {
    return userSet;
}
public void setUserSet(Set<User> userSet) {
    this.userSet = userSet;
}
@Override
public String toString() {
    return "Right [rightID=" + rightID + ", name=" + name + ", userSet="
            + userSet.size() + "]";
}

}
[/code]

发布成web service后 写了一个
[code="java"]
public class ClientTest {

public static void main(String[] args) throws Exception {
     JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
     factory.setServiceClass(UserWebservice.class);
     factory.setAddress("http://localhost:8080/TwoTablesSSH/services/UserWebService");

     UserWebservice webservice = (UserWebservice) factory.create();
    ]User user = webservice.queryByID(1);
     System.out.println(user);
}

}
[/code]
结果出错了
Exception in thread "main" org.apache.cxf.binding.soap.SoapFault: Marshalling Error: A cycle is detected in the object graph. This will cause infinitely deep XML: User [userName=admin, userPassword=admin, mobile=admin, email=admin, nickname=admin, region=null, birthday=2011-11-25 17:16:37.0, telephone=null, address=null, postcode=null, signature=null, imageUrl=null, userID=1, rightSet=4] -> Right [rightID=1, name=UpdateRight, userSet=1] -> User [userName=admin, userPassword=admin, mobile=admin, email=admin, nickname=admin, region=null, birthday=2011-11-25 17:16:37.0, telephone=null, address=null, postcode=null, signature=null, imageUrl=null, userID=1, rightSet=4]
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:141)
at $Proxy30.queryByID(Unknown Source)
at com.tianxiao.whut.client.ClientTest.main(ClientTest.java:22)

出现了循环引用对象的问题,看网上的解决办法,将@XmlTransient放在了Right类中的
@XmlTransient
public Set getUserSet() {
return userSet;
}

结果 出现了无法实例化User的问题
org.apache.cxf.interceptor.Fault: Unmarshalling Error: Unable to create an instance of com.tianxiao.whut.domain.User
at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:801)
at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:642)
at org.apache.cxf.jaxb.io.DataReaderImpl.read(DataReaderImpl.java:156)
at org.apache.cxf.interceptor.DocLiteralInInterceptor.handleMessage(DocLiteralInInterceptor.java:109)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:797)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1626)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1493)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1401)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:648)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:533)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:463)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:366)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:319)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:88)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:134)
at $Proxy31.queryByID(Unknown Source)
at com.tianxiao.whut.client.ClientTest.main(ClientTest.java:22)
Caused by: javax.xml.bind.UnmarshalException

  • with linked exception: [javax.xml.bind.UnmarshalException: Unable to create an instance of com.tianxiao.whut.domain.User
  • with linked exception: [java.lang.InstantiationException]] at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(UnmarshallerImpl.java:434) at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:371) at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:348) at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:778) ... 20 more Caused by: javax.xml.bind.UnmarshalException: Unable to create an instance of com.tianxiao.whut.domain.User
  • with linked exception: [java.lang.InstantiationException] at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:662) at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:258) at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.createInstance(UnmarshallingContext.java:629) at com.sun.xml.bind.v2.runtime.unmarshaller.StructureLoader.startElement(StructureLoader.java:185) at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:501) at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:480) at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.handleStartElement(StAXStreamConnector.java:247) at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.bridge(StAXStreamConnector.java:181) at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:369) ... 22 more Caused by: javax.xml.bind.UnmarshalException: Unable to create an instance of com.tianxiao.whut.domain.User
  • with linked exception: [java.lang.InstantiationException] ... 31 more Caused by: java.lang.InstantiationException at sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(Unknown Source) at java.lang.reflect.Constructor.newInstance(Unknown Source) at com.sun.xml.bind.v2.ClassFactory.create0(ClassFactory.java:122) at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.createInstance(ClassBeanInfoImpl.java:282) at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.createInstance(UnmarshallingContext.java:623) ... 28 more Exception in thread "main" org.apache.cxf.interceptor.Fault: Unmarshalling Error: Unable to create an instance of com.tianxiao.whut.domain.User at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:141) at $Proxy31.queryByID(Unknown Source) at com.tianxiao.whut.client.ClientTest.main(ClientTest.java:22) Caused by: javax.xml.bind.UnmarshalException
  • with linked exception: [javax.xml.bind.UnmarshalException: Unable to create an instance of com.tianxiao.whut.domain.User
  • with linked exception: [java.lang.InstantiationException]] at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(UnmarshallerImpl.java:434) at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:371) at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:348) at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:778) at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:642) at org.apache.cxf.jaxb.io.DataReaderImpl.read(DataReaderImpl.java:156) at org.apache.cxf.interceptor.DocLiteralInInterceptor.handleMessage(DocLiteralInInterceptor.java:109) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263) at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:797) at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1626) at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1493) at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1401) at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56) at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:648) at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263) at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:533) at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:463) at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:366) at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:319) at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:88) at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:134) ... 2 more Caused by: javax.xml.bind.UnmarshalException: Unable to create an instance of com.tianxiao.whut.domain.User
  • with linked exception: [java.lang.InstantiationException] at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:662) at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:258) at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.createInstance(UnmarshallingContext.java:629) at com.sun.xml.bind.v2.runtime.unmarshaller.StructureLoader.startElement(StructureLoader.java:185) at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:501) at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:480) at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.handleStartElement(StAXStreamConnector.java:247) at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.bridge(StAXStreamConnector.java:181) at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:369) ... 22 more Caused by: javax.xml.bind.UnmarshalException: Unable to create an instance of com.tianxiao.whut.domain.User
  • with linked exception: [java.lang.InstantiationException] ... 31 more Caused by: java.lang.InstantiationException at sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(Unknown Source) at java.lang.reflect.Constructor.newInstance(Unknown Source) at com.sun.xml.bind.v2.ClassFactory.create0(ClassFactory.java:122) at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.createInstance(ClassBeanInfoImpl.java:282) at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.createInstance(UnmarshallingContext.java:623) ... 28 more

请教各位大虾,这是怎么回事 ,好像变糟糕了 !!!

2个回答

jaxb提供了有这种扩展。(CycleRecoverable接口) 解决循环引用问题,你试试:

[code="java"]
public abstract class User implements CycleRecoverable{

//...
public Object onCycleDetected(Context arg0) {
  Company temp = new Company ();
  temp.setId(id);
  return temp;
  }

}

public class Right {

}

[/code]

在你循环引用的对象中都实现CycleRecoverable 接口,实现onCycleDetected 方法,

当出现循环引用时,使用一个temp对象替换当前的this

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!