使用Maven 插件 cxf-codegen-plugin生成WebService测试程序

WebService的测试程序开发

CXF 中包含了一个 Maven 插件 cxf-codegen-plugin,能够将 Wsdl 文件动态生成 webservice 本地类。下面针对Apace cxf 进行介绍如何配置,以及webservice中的几种常见安全验证方式。

Apache CXF简介

Apache CXF = Celtix + XFire。Apache CXF 是一个开源的 Services 框架,CXF 利用 Frontend 编程 API 来构建和开发 Web Services , 支持 SOAP, XML/HTTP, RESTful HTTP, 和 CORBA ,并且可以在多种协议上运行,如HTTP, JMS 和 JBI.

官方地址:http://cxf.apache.org/

将WSDL文件转化为Java代码

CXF 中包含了一个 Maven 插件 cxf-codegen-plugin,能够将 Wsdl 文件动态生成 webservice 本地类。 具体方法:在eclipse中建立maven项目,然后将pom中增加配置如下,然后运行mvn run,mvn install, mvn test等,即可生成代码。 
详细的pom.xml配置文件见最下方附注。

Maven 配置

<plugin>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-codegen-plugin</artifactId>
    <version>${cxf.version}</version>
    <executions>
        <execution>
            <id>generate-sources</id>
            <phase>generate-sources</phase>
            <configuration>
                <sourceRoot>${project.build.directory}</sourceRoot>
                <wsdlOptions>
                    <wsdlOption>
                        <wsdl>http://172.0.0.1:8080/myService.wsdl</wsdl>
                    </wsdlOption>
                    <wsdlOption>
                        <wsdl>${basedir}/src/main/resources/myService.wsdl</wsdl>
                    </wsdlOption>
                </wsdlOptions>
            </configuration>
            <goals>
                <goal>wsdl2java</goal>
            </goals>
        </execution>
    </executions>
</plugin>

使用上述maven插件,代码会自动生成客户端,其名称类似于class ServiceName_ServicePort_Client,不过自动生成的客户端代码比较繁琐,不便于维护,建议自己重新建立自己的测试用例。copy艳超的代码如下:

 @Test
public void blurNameTest(){
     //实例化接口
     CompanyRemote companyRemoteClient =  new CompanyRemoteImplService().   
    //调用接口中的方法                                      getCompanyRemoteImplPort();
     companyList = companyRemoteClient.getAllCompanysByBlurName("百度");

     System.out.println(companyList.size());
}

WebService客户端的安全认证

WebService客户端与服务器端进行通信时,经常需要在soap文件中增加安全认证信息。在我的项目中,涉及到了2种安全认证方式:

1. 在soap文件的header中增加用户名和密码校验

    <soap:Envelope>
        <soapenv:Header>
            <wsse:Security ...>
                <wsse:UsernameToken wsu:Id="UsernameToken-1">
                    <wsse:Username>test</wsse:Username>
                    <wsse:Password Type=".."...>123456</wsse:Password>
                    <wsse:Nonce EncodingType="...">4AJ7sPA8NRQ74faqignO3g==</wsse:Nonce>
                    <wsu:Created>2013-06-20T12:33:05.001Z</wsu:Created>
                </wsse:UsernameToken>
            </wsse:Security>
        </soapenv:Header>

        <soapenv:Body>
        ...
        </soapenv:Body>
    </soap:Envelope>

方法为建立一个拦截器

import org.apache.ws.security.WSPasswordCallback;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import java.io.IOException; 

/**
 * Created with IntelliJ IDEA.
 * User: shenyanchao
 * Date: 5/15/13
 * Time: 2:00 PM
 */
public class WsClientAuthHandler implements CallbackHandler {


    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
        for (int i = 0; i < callbacks.length; i++) {
            WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
            pc.setIdentifier("test");
            pc.setPassword("123456");// ▲【这里必须设置密码】▲
        }
    }
}

然后在客户端中添加该拦截器

    FeeFinanceService_Service server=new FeeFinanceService_Service();
    String username = "test";//服务器端分配的用户名
    String password = "123456";//服务器端分配的密码
    FeeFinanceService port = server.getFeeFinanceServicePort();

    Client client = ClientProxy.getClient(port);

    Map<String, Object> props = new HashMap<String, Object>();

    props.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
    props.put(WSHandlerConstants.USER, "cxfclient");
    props.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
    props.put(WSHandlerConstants.PW_CALLBACK_CLASS, WsClientAuthHandler.class.getName());

    WSS4JOutInterceptor wss4jOut = new WSS4JOutInterceptor(props);

    client.getOutInterceptors().add(wss4jOut);

    List<JtReq> reqlist = new ArrayList<JtReq>();
    JtReq req = new JtReq();
    req.setBusinessNumb("T");

2. 安全验证在soap中插入,但是实际发送soap文件时会出现在html的头文件中

    POST /cmssoap/ws/fee_biz_service HTTP/1.1[\r][\n]
    Accept-Encoding: gzip,deflate
    Content-Type: text/xml;charset=UTF-8
    SOAPAction: 
    Authorization: Basic dGVzdDoxMjM0NTY=
    Content-Length: 1475
    Host: 10.237.4.242:8900

    <soap:Envelope>
    ...
    </soap:Envelope>

该程序,可以直接在函数中增加授权验证

    public void testInsert() throws ValidationException_Exception {

      String username = "test";//服务器端分配的用户名
      String password = "123456";//服务器端分配的密码

    Authenticator.setDefault(new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("test",
                                                  "123456".toCharArray());
            }
        });



    FeeBizService_Service server=new FeeBizService_Service();

    FeeBizService port = server.getFeeBizServicePort();


    BindingProvider bp = (BindingProvider)port;

    Map<String,Object> context = bp.getRequestContext();

    context.put(BindingProvider.USERNAME_PROPERTY, username);
    context.put(BindingProvider.PASSWORD_PROPERTY, password);



    List<Fee> fees = new ArrayList<Fee>();

   String str = port.sendFee(fees);

3. 在soap的header中直接增加用户名和密码

    <soap:Envelope>
        <soapenv:Header>        
            <wsse:Username>youthflies</wsse:Username>
            <wsse:Password>youthflies</wsse:Password>
        </soapenv:Header>

        <soapenv:Body>
        ...
        </soapenv:Body>
    </soap:Envelope>

建立拦截器

/**
 * @author youthflies
 * 自定义的soap拦截器,用来添加header信息
 */
public class SoapHeaderInterceptor extends AbstractSoapInterceptor
{
    public SoapHeaderInterceptor()
    {
        super(Phase.WRITE);
    }

    @Override
    public void handleMessage(SoapMessage message) throws Fault
    {
        // TODO Auto-generated method stub   
        List headers=message.getHeaders(); 
        headers.add(getHeader("username", "youthflies"));
        headers.add(getHeader("password", "youthflies"));
    }

    //http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl
    private Header getHeader(String key, String value) 
    { 
        QName qName=new QName("http://webservice.webxml.com.cn/", key); 

        Document document=DOMUtils.createDocument(); 
        Element element=document.createElementNS("http://webservice.webxml.com.cn/", key); 
        element.setTextContent(value); 

        SoapHeader header=new SoapHeader(qName, element); 
        return(header); 
    }

}

case中,添加拦截器:

    //实例化接口实现类
   MobileCodeWS mobileCodeWS = new MobileCodeWS();
   //实例化接口
   MobileCodeWSSoap mobileCodeWSSoap = mobileCodeWS.getMobileCodeWSSoap();

   Client client = ClientProxy.getClient(mobileCodeWSSoap);
   client.getOutInterceptors().add(new SoapHeaderInterceptor());

   //调用接口中的方法
   System.out.println(mobileCodeWSSoap.getMobileCodeInfo("13898767654", ""));

附录一:

SVN上生成webservice测试文件的代码路径:(请忽略SVN地址,外面的人没法用)

https://xxx.xxx.xxx/myspace/iteqa/InterfaceTest/cxf4ws

生成的代码会在src/main/java路径下面,而自己的测试代码可以放到src/test下面,提交到SVN时,只提交src/test下的文件即可。

完整的pom文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.yourGroupId</groupId>
    <artifactId>yourArtifactId</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <cxf.version>2.7.3</cxf.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>6.8</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-ws-security</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.ws.security</groupId>
            <artifactId>wss4j</artifactId>
            <version>1.6.10</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-bindings-soap</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>${cxf.version}</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <executable>javac</executable>
                    <compilerVersion>1.6</compilerVersion>
                    <fork>true</fork>
                    <verbose>true</verbose>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.cxf</groupId>
                <artifactId>cxf-codegen-plugin</artifactId>
                <version>${cxf.version}</version>

                <executions>
                    <execution>
                        <id>generate-sources</id>
                        <phase>generate-sources</phase>
                        <configuration>
                            <sourceRoot>${project.build.sourceDirectory}</sourceRoot>
                            <defaultOptions>
                                <extraargs>
                                    <extraarg>-impl</extraarg>
                                    <extraarg>-verbose</extraarg>
                                    <extraarg>-validate</extraarg>
                                    <!--<extraarg>-client</extraarg>-->
                                </extraargs>
                            </defaultOptions>
                            <wsdlOptions>
                                <!--<wsdlOption>
                                    <wsdl>http://itebeta.xxx.com:8102/webservice/CompanyService?wsdl</wsdl>
                                </wsdlOption>
                                <wsdlOption>
                                    <wsdl>http://itebeta.xxx.com:8102/webservice/CompanyServiceN?wsdl</wsdl>
                                </wsdlOption>
                                <wsdlOption>
                                    <wsdl>http://itebeta.xxx.com:8102/webservice/UserServiceN?wsdl</wsdl>
                                </wsdlOption>-->
                                <wsdlOption>
                                    <wsdl>http://xxx.xxx.4.242:8900/cmssoap/ws/fee_finance_service?wsdl</wsdl>
                                    <extraargs>
                                        <!--<extraarg>-exsh</extraarg>
                                        <extraarg>true</extraarg>-->
                                        <!--<extraarg>-all</extraarg>-->
                                    </extraargs>
                                </wsdlOption>

                            </wsdlOptions>
                        </configuration>
                        <goals>
                            <goal>wsdl2java</goal>
                        </goals>
                    </execution>
                </executions>

            </plugin>

        </plugins>

 <pluginManagement>  
        <plugins>   
            <plugin>  
                <groupId>org.eclipse.m2e</groupId>  
                <artifactId>lifecycle-mapping</artifactId>  
                <version>1.0.0</version>  
                <configuration>  
                    <lifecycleMappingMetadata>  
                        <pluginExecutions>  
                            <pluginExecution>  
                                <pluginExecutionFilter>  
                                    <groupId>  
                                        org.apache.cxf  
                                    </groupId>  
                                    <artifactId>  
                                        cxf-codegen-plugin  
                                    </artifactId>  
                                    <versionRange>  
                                        [2.1.4,)  
                                    </versionRange>  
                                    <goals>  
                                        <goal>wsdl2java</goal>  
                                    </goals>  
                                </pluginExecutionFilter>  
                                <action>  
                                    <ignore></ignore>  
                                </action>  
                            </pluginExecution>  
                        </pluginExecutions>  
                    </lifecycleMappingMetadata>  
                </configuration>  
            </plugin>  
        </plugins>  
    </pluginManagement>  
    </build>
</project>

你可能感兴趣的:(maven,测试,插件,接口测试)