cxf动态调用wsdl的一个冲突以及解决

cxf发布服务,调用服务的博客很多,这里也就简单贴一下代代码。

环境如下:spring+cxf (maven环境)

<cxf.version>2.7.11</cxf.version>

<!-- SOAP begin -->
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-core</artifactId>
            <version>${cxf.version}</version>
            <exclusions>
                <!-- use javax.mail.mail instead -->
                <exclusion>
                    <groupId>org.apache.geronimo.specs</groupId>
                    <artifactId>geronimo-javamail_1.4_spec</artifactId>
                </exclusion>
                <!-- use javax.activation.activation instead -->
                <exclusion>
                    <groupId>org.apache.geronimo.specs</groupId>
                    <artifactId>geronimo-activation_1.1_spec</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>${cxf.version}</version>
            <exclusions>
                <!-- see above -->
                <exclusion>
                    <groupId>org.apache.geronimo.specs</groupId>
                    <artifactId>geronimo-javamail_1.4_spec</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.geronimo.specs</groupId>
                    <artifactId>geronimo-activation_1.1_spec</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <!-- SOAP end -->
View Code

服务端(jetty环境):

@WebService
public interface ICommand {
    
    /**
     * 通用调用
     * @param fromApp
     * @return
     */
    public String isConnection(@WebParam(name="fromApp") String fromApp);
    
    public String sendCommand(@WebParam(name="fromApp")String fromApp, @WebParam(name="command")String command);
    
}
@WebService
public class CommandImpl implements ICommand {

    private final static Logger logger = LoggerFactory.getLogger(CommandImpl.class);
        
    @Override
    public String isConnection(String fromApp) {
        logger.info("from:" + fromApp);
        return "ok";
    }
    
    @Override
    public String sendCommand(String fromApp, String command) {
        logger.info("from:" + fromApp + ",name:" + command);
        // 调用自己生
        return "response:[" + command + "]";
    }
}
View Code

spring配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
 xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
 xmlns:jaxws="http://cxf.apache.org/jaxws"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans.xsd
 http://www.springframework.org/schema/tx
 http://www.springframework.org/schema/tx/spring-tx.xsd
 http://www.springframework.org/schema/aop
 http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context.xsd
 http://cxf.apache.org/jaxws
 http://cxf.apache.org/schemas/jaxws.xsd">  
  <!--CXF配置-->
   <import resource="classpath:META-INF/cxf/cxf.xml"/>
   <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>
   <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>

      <!--服务端发布的webservice 和下面的配置一样
      <jaxws:endpoint id="command" implementor="cn.edu.bupt.service.soa.CommandImpl" address="/Command"/>
-->
    <bean id="command" class="cn.edu.bupt.service.soa.CommandImpl"/>   
    <jaxws:endpoint id="commandWebService" address="/Command" implementorClass="cn.edu.bupt.service.soa.CommandImpl">  
        <jaxws:implementor ref="command"/>    
    </jaxws:endpoint>
</beans>
View Code

客户端配置:

 <jaxws:client id="commandClient" address="http://localhost:8088/virtual-network/webservice/Command" serviceClass="cn.edu.bupt.service.soa.ICommand"/>
    

采用bean调用:

public static void main(String[] args){

   ApplicationContext context = new ClassPathXmlApplicationContext("spring-cxf.xml"); 
  ICommand helloWorld=(ICommand)context.getBean("commandClient");
  System.out.println(helloWorld.sendCommand("helloworld","Test"));
}
View Code

这边准备用cxf动态调用:

 public static void main(String[] args){
JaxWsDynamicClientFactory  factory =JaxWsDynamicClientFactory.newInstance();
     String url = "http://localhost:8088/virtual-network/webservice/Command?wsdl";
     org.apache.cxf.endpoint.Client client =factory.createClient(url);
      //url为调用webService的wsdl地址 
    //QName也可以
     //QName name=new QName("http://soa.service.bupt.edu.cn/","isConnection");  
     try {
//         Object[] obj =client.invoke(name, "helloworld");
         Object[] obj =client.invoke("isConnection", "helloworld");
         System.out.println("resp:"+obj[0]);
     } catch (Exception e) {
      e.printStackTrace();
     }
 }

由于我客户端和服务端是一起运行,报出异常:

Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    at com.sun.tools.internal.xjc.reader.Ring.get(Ring.java:87)
    ... 23 more
Caused by: java.lang.NoSuchFieldError: REFLECTION
    at com.sun.tools.internal.xjc.model.nav.NavigatorImpl.getBaseClass(NavigatorImpl.java:59)
    at com.sun.tools.internal.xjc.model.nav.NavigatorImpl.getBaseClass(NavigatorImpl.java:44)
    at com.sun.xml.internal.bind.v2.model.core.Adapter.<init>(Adapter.java:73)

这个是为什么,因为项目引入的tools.jar与jaxb-impl.jar冲突了。

用mvn dependency:tree > tree.txt 导入包引用路径,发现是druid引入的tools导致的

[INFO] +- com.alibaba:druid:jar:1.0.9:compile
[INFO] |  +- com.alibaba:jconsole:jar:1.8.0:system
[INFO] |  - com.alibaba:tools:jar:1.8.0:system

排除一下

<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>${druid.version}</version>
            <exclusions>
                <exclusion>
                  <groupId>com.alibaba</groupId>
                  <artifactId>jconsole</artifactId>
                </exclusion>
                <exclusion>
                  <groupId>com.alibaba</groupId>
                  <artifactId>tools</artifactId>
                </exclusion>
            </exclusions> 
</dependency>
View Code

就解决了该冲突。

 参考:

http://www.cnblogs.com/hoojo/archive/2011/03/30/1999563.html

http://jishiweili.iteye.com/blog/2086100

http://www.blogjava.net/sxyx2008/archive/2010/09/15/332058.html

http://www.cnblogs.com/hoojo/archive/2011/03/30/1999563.html

原文地址:https://www.cnblogs.com/hero4china/p/cxf-wsdl-REFLECTION.html