使用Apache CXF调用webservice接口

最近在RestCloud平台中调用webservice时遇到以下问题,总结记录下:

Apache CXF调用webservice接口可以有两种方式实现:

  1. 一是动态调用webservice即不用生成客户端代码但是要调用复杂的webservice服务比较难实现,特别是调用.net的ws接口比较难
  2. 二是生成client java客户端代码然后通过java类来进行调用,如果在生成 wsdl的时候出错也是很难办的了,只有采用模拟请求soap的xml来调用了

动态调用代码如下:

import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;  

import org.apache.cxf.endpoint.Client;  

import java.lang.reflect.Method;  

public class JaxWsDynamicClient {  

    public static void main(String str[]) throws Exception {  

        JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();  

        Client client = dcf.createClient("http://localhost:8081/mywebservice?wsdl");  

        Object[] response = client.invoke("方法名",方法参数);  

        System.out.println("调用结果 is " + response[0]);  

    }  

}  

这是Apache cxf网上关于动态调用的说明

Many WSDLs will have more complex types though. In this case the JaxWsDynamicClientFactory takes care of generating Java classes for these types. For example, we may have a People service which keeps track of people in an organization. In the sample below we create a Person object that was generated for us dynamically and send it to the server using the addPerson operation:

JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();

Client client = dcf.createClient("people.wsdl", classLoader);

 

 

Object person = Thread.currentThread().getContextClassLoader().loadClass("com.acme.Person").newInstance();

 

Method m = person.getClass().getMethod("setName", String.class);

m.invoke(person, "Joe Schmoe");

 

client.invoke("addPerson", person);

You may be asking yourself the following question: "Where did the class name 'com.acme.Person' come from?"

One way to get the class names is to run wsdl2java and examine the results. The dynamic client factory uses the same code generator as that tool. Another way is to walk the CXF service model. This has the advantage that it delivers Class objects directly, so you don't need to obtain the correct class loader reference and run loadClass.

The wsdl_first_dynamic_client sample uses this approach. Read the file 'ComplexClient.java' to see the process, which uses some of the java.bean classes to simplify the code slightly.

注意上面这段话,主要说明 com.acme.Person从那里来,可以用wsdl2java工具生成一个,不过这样就觉得没什么意了,因为都已经生成class还使用动态调用显然没有必要了,我还以为cxf可以强大到根据wsdl文件自动使用反射来生成一个呢,看来是想多了。

如果wsdl有用户名和密码就又麻烦了,这时要使用cxf的拦载器才能实现了

二是生成wsdl代码来进行调用,这个是大家普通采用的方式

首先需要下载cxf的tools工具包,利用里面的wsdl2java工具对wsdl生成client java代码,如果wsdl有用户名和密码验证可以先保存到本地再生成java代码就可以了。

进入解压的cxf文件夹 

在cmd命令中输入:wsdl2java -d D:\\src -client http://localhost:8080/test?wsdl 就可以生成client端代码和调用示例了,直接把调用示例的java代码改下就可以调用webservice了

 

wsdl2java还有很多参数可以选,可以定义复杂的生成规则:

带-符号的表示是选项后面要带参数,最后一个是wsdl文件的路径.

Option

Interpretation

-?,-h,-help

Displays the online help for this utility and exits.

-fe frontend-name

Specifies the frontend. Default is JAXWS. Currently supports only JAXWS frontend and a "jaxws21" frontend to generate JAX-WS 2.1 compliant code.

-db databinding-name

Specifies the databinding. Default is jaxb. Currently supports jaxb, xmlbeans, sdo (sdo-static and sdo-dynamic), and jibx.

-wv wsdl-version

Specifies the wsdl version .Default is WSDL1.1. Currently suppports only WSDL1.1 version.

-p [ wsdl-namespace= ] PackageName

Specifies zero, or more, package names to use for the generated code. Optionally specifies the WSDL namespace to package name mapping.

-sn service-name

The WSDL service name to use for the generated code.

-b binding-name

Specifies JAXWS or JAXB binding files or XMLBeans context files. Use multiple -b flags to specify multiple entries.

-catalog catalog-file-name

Specify catalog file to map the imported wsdl/schema

-d output-directory

Specifies the directory into which the generated code files are written.

-compile

Compiles generated Java files.

-classdir compile-class-dir

Specifies the directory into which the compiled class files are written.

-client

Generates starting point code for a client mainline.

-clientjar jar-file-name

Generates the jar file which contains all the client classes and wsdl;the specified wsdlLocation won't work when the -clientJar is defined.

-server

Generates starting point code for a server mainline.

-impl

Generates starting point code for an implementation object.

-all

Generates all starting point code: types, service proxy, service interface, server mainline, client mainline, implementation object, and an Ant build.xml file.

-ant

Specify to generate an Ant build.xml script.

-autoNameResolution

Automatically resolve naming conflicts without requiring the use of binding customizations.

-defaultValues=[DefaultValueProvider impl]

Specifies that default values are generated for the impl and client. You can also provide a custom default value provider. The default provider is RandomValueProvider

-nexclude schema-namespace [=java-packagename]

Ignore the specified WSDL schema namespace when generating code. This option may be specified multiple times. Also, optionally specifies the Java package name used by types described in the excluded namespace(s).

-exsh (true/false)

Enables or disables processing of implicit SOAP headers (i.e. SOAP headers defined in the wsdl:binding but not wsdl:portType section.) Processing the SOAP headers requires the SOAP binding jars available on the classpath which was not the default in CXF 2.4.x and older. You may need to add a dependency to cxf-rt-binding-soap for this flag to work. Default is false.

-dns (true/false)

Enables or disables the loading of the default namespace package name mapping. Default is true and http://www.w3.org/2005/08/addressing=org.apache.cxf.ws.addressing namespace package mapping will be enabled.

-dex (true/false)

Enables or disables the loading of the default excludes namespace mapping. Default is true.

-validate

Enables validating the WSDL before generating the code.

-keep

Specifies that the code generator will not overwrite any preexisting files. You will be responsible for resolving any resulting compilation issues.

-wsdlLocation wsdlLocation

Specifies the value of the @WebServiceClient annotation's wsdlLocation property.

-xjc

Specifies a comma separated list of arguments that are passed directly to the XJC processor when using the JAXB databinding. A list of available XJC plugins can be obtained using -xjc-X.

-noAddressBinding

For compatibility with CXF 2.0, this flag directs the code generator to generate the older CXF proprietary WS-Addressing types instead of the JAX-WS 2.1 compliant WS-Addressing types.

-v

Displays the version number for the tool.

-verbose

Displays comments during the code generation process.

-quiet

Suppresses comments during the code generation process.

-exceptionSuper

superclass for fault beans generated from wsdl:fault elements (defaults to java.lang.Exception)

-reserveClass classname

Used with -autoNameResolution, defines a class names for wsdl-to-java not to use when generating classes. Use this option multiple times for multiple classes.

-allowElementReferences<=true>

(or -aer) If true, disregards the rule given in section 2.3.1.2(v) of the JAX-WS 2.2 specification disallowing element references when using wrapper-style mapping.

-asyncMethods=foo,bar,...

List of subsequently generated Java class methods to allow for client-side asynchronous calls, similar to enableAsyncMapping in a JAX-WS binding file.

-bareMethods=foo,bar,...

List of subsequently generated Java class methods to have wrapper style (see below), similar to enableWrapperStyle in JAX-WS binding file.

-mimeMethods=foo,bar,...

List of subsequently generated Java class methods to enable mime:content mapping, similar to enableMIMEContent in JAX-WS binding file.

-faultSerialVersionUID

How to generate suid of fault exceptions. Use NONE, TIMESTAMP, FQCN, or a specific number. Default is NONE.

-mark-generated

Adds the @Generated annotation to classes generated.

-suppress-generated-date Suppresses writing the current timestamp in the generated file (since CXF version 3.2.2)

wsdlurl

The path and name of the WSDL file to use in generating the code.

 

总之要应付企业已有的业务系统的ws的接口是比较麻烦的事,所以还是使用Rest API接口是比较好的解决方案。

你可能感兴趣的:(Java开发技术)