• 使用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[ ][ ]
    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>

  • 相关阅读:
    如何禁用 Azure 虚拟机的日期时间同步
    Java 如何启用 ARM 虚拟机诊断
    File类的源码学习
    Trie树学习
    Hadoop自带Sort例子分析
    java.io.IOException: Illegal partition for 67 (-1)
    Java IO、网络编程、NIO、Netty、Hessian、RPC、RMI的学习路线
    MapReduce中的排序(附代码)
    CAP理论学习
    Harvard数据库课程CS 265: Research Topics in Database Systems
  • 原文地址:https://www.cnblogs.com/grimm/p/12363700.html
Copyright © 2020-2023  润新知