从 Java 中的参数化类生成 Web 服务(WSDL 1.2 或更高版本)(Apache CXF、Axis 2)

发布于 2024-09-11 20:45:42 字数 2153 浏览 4 评论 0原文

我有一个抽象类,如下所示。

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 上。

当我使用 Apache CXF 生成 Web 服务时,出现以下异常:

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 服务?

I have an abstract class that looks as follows.

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

My Service looks like this

public interface EntityService {

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

and my implementation is on class EntityServiceImpl.

When I do a Web Service generation with Apache CXF, I get the following exception:

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)

My question:

How do I generate a Web Service that has Parametrized Types or uses Generics?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

紫轩蝶泪 2024-09-18 20:45:42

看到没有人回答这个问题,我就自己回答一下吧。

对于 Apache CXF(WS 生成的 bean),所有 getter 都会返回一个 not null 对象,这意味着如果变量为 null,则会发生以下情况:

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

如您所见,以下内容会导致 CXF 出现异常:

  • Serialized 类是一个接口,因此如果我有一个 Serialized 类型的变量,则在 CXF 生成客户端源代码时无法定义 new Serialized()
  • 所有对象必须实现一个public构造函数。

不满足这两个原则,会导致上述异常。


解决方案

对于属性私有列表父母,我们添加了这个。

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

希望这对某人有帮助。

Seeing that nobody answered this question, I'll answer this myself.

With Apache CXF, A WS generated bean, all getters return a not null object, meaning that if a variable is null, this is what happens:

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

As you can see, this following causes an exception for CXF:

  • A Serializable class is an interface, so if I have a variable of type Serializable, new Serializable() cannot be defined when CXF generates client source-code.
  • All Object must implement a public constructor.

Failure for the 2 principles, causes the exception above.


Solution

For attribute private List<? extends User> parents, we added this.

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

And for interfaces, we used the XmlJavaTypeAdapter and wrote an adapter for every implemented subclasses of that interface,

e.g.

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

Hope this helps someone.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文