2010-07-29 47 views
2

我有一個抽象類,如下所示。從Java中的參數化類生成Web服務(WSDL 1.2或更高版本)(Apache CXF,Axis 2)

public abstract class Entity<PK extends Serializable> implements Serializable { 

    private PK id; 

    //getters and setters generated here.... 
} 

public class User extends Entity<Long> { 

    //all attributes, getters and setters are done here... 
} 

我的服務看起來像這樣

public interface EntityService { 

    public void create(Entity<? extends Serializable> entity) throws ServiceException; 
    public boolean delete(Entity<? extends Serializable> entity) throws ServiceException; 
} 

和我的實現是EntityServiceImpl類。

當我做一個Web服務產生與Apache CXF,我得到以下異常:

Error: java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.reflect.TypeVariable 

java.lang.RuntimeException: java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.reflect.TypeVariable 
    at org.apache.cxf.frontend.AbstractServiceFactory.createService(AbstractServiceFactory.java:41) 
    at org.apache.cxf.tools.java2wsdl.processor.JavaToWSDLProcessor.process(JavaToWSDLProcessor.java:128) 
    at org.apache.cxf.tools.java2ws.JavaToWSContainer.processWSDL(JavaToWSContainer.java:109) 
    at org.apache.cxf.tools.java2ws.JavaToWSContainer.execute(JavaToWSContainer.java:75) 
    at org.apache.cxf.tools.common.toolspec.ToolRunner.runTool(ToolRunner.java:103) 
    at org.apache.cxf.tools.common.toolspec.ToolRunner.runTool(ToolRunner.java:58) 
    at org.apache.cxf.tools.common.toolspec.ToolRunner.runTool(ToolRunner.java:40) 
    at org.apache.cxf.tools.java2ws.JavaToWS.run(JavaToWS.java:77) 
    at org.apache.cxf.tools.java2ws.JavaToWS.main(JavaToWS.java:45) 
Caused by: java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.reflect.TypeVariable 
    at org.apache.cxf.jaxb.JAXBContextInitializer.addType(JAXBContextInitializer.java:232) 
    at org.apache.cxf.jaxb.JAXBContextInitializer.addType(JAXBContextInitializer.java:211) 

我的問題:

如何生成已參數化類型或使用泛型Web服務?

回答

2

看到沒有人回答這個問題,我會自己回答。

與Apache CXF,A WS生成豆,所有的getter方法返回一個not null對象,這意味着如果一個變量是空,這是發生了什麼:

public List<? extends User> getParents() { 
     if (parents == null) { 
      parents = new ArrayList<User>(); 
     } 
     return this.parents; 
    } 

正如你所看到的,這下導致異常爲CXF:

  • Serializable類是一個接口,因此,如果我有Serializable類型的變量,new Serializable()時不能CXF生成客戶源代碼中定義的。
  • 所有對象必須實現一個public構造函數。

2原則失敗導致上述異常。


解決方案

對於屬性private List<? extends User> parents,我們增加了這一點。

@XmlElements({ 
    @XmlElement(type=Man.class), 
    @XmlElement(type=Female.class), 
    @XmlElement(type=Child.class) 
}) 
private List<? extends User> parents; 

而對於接口,我們使用了XmlJavaTypeAdapter並寫了該接口的每個子類中實現一個適配器,

例如

public class IntegerConstraintBaseAdapter extends XmlAdapter<IntegerConstraint, ConstraintBase<Integer>> { 

    /* (non-Javadoc) 
    * @see javax.xml.bind.annotation.adapters.XmlAdapter#marshal(java.lang.Object) 
    */ 
    @Override 
    public IntegerConstraint marshal(ConstraintBase<Integer> v) throws Exception { 
     // TODO Auto-generated method stub 
     return null; 
    } 

    /* (non-Javadoc) 
    * @see javax.xml.bind.annotation.adapters.XmlAdapter#unmarshal(java.lang.Object) 
    */ 
    @Override 
    public ConstraintBase<Integer> unmarshal(IntegerConstraint v) throws Exception { 
     // TODO Auto-generated method stub 
     return null; 
    } 
} 

希望這可以幫助別人。