CXF 发布WebService - 客户端调用

1. 一个客户端用户名密码回调类

package org.demo.ws.client;

import java.io.IOException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.ws.security.WSPasswordCallback;

public class ClientPasswordCallback implements CallbackHandler
{
    @Override
    public void handle(Callback[] callbacks) throws IOException,
            UnsupportedCallbackException
    {
        WSPasswordCallback pwCallback = (WSPasswordCallback)callbacks[0];
        pwCallback.setIdentifier("user1");
        pwCallback.setPassword("password1");
    }
}

2. src/ws-client.xml

<?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:jaxws="http://cxf.apache.org/jaxws"
    xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd" >
    
    <bean id="clientPasswordCallback" class="org.demo.ws.client.ClientPasswordCallback" />
    <bean id="wSS4JOutInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
        <constructor-arg>
            <map>
                <entry key="action" value="UsernameToken" />
                <entry key="passwordType" value="PasswordText" />
                <entry key="user" value="cxfClient" />
                <entry key="addUTElements" value="Nonce Created" />
                <entry key="passwordCallbackRef">
                    <ref bean="clientPasswordCallback" />
                </entry>
            </map>
        </constructor-arg>
    </bean>
    
    <jaxws:client id="helloWorld" serviceClass="org.demo.ws.HelloWorld" 
        address="http://localhost:8080/spring/services/hello">
        <jaxws:outInterceptors>
            <ref bean="wSS4JOutInterceptor" />
        </jaxws:outInterceptors>
    </jaxws:client>
    
</beans>

3. 一个客户端测试类

package org.demo.ws.client;

import org.demo.ws.HelloWorld;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class WsClient
{
    
    /**
     * @param args
     */
    public static void main(String[] args)
    {
        AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("ws-client.xml");
        HelloWorld bean = (HelloWorld)ctx.getBean("helloWorld");
        String result = bean.sayHi("xiao ming");
        System.out.println("result is " + result);
    }
    
}

4. 如果不使用 spring 框架,则可以使用如下方式调用 WebService

package org.demo.ws.client;

import java.util.HashMap;
import java.util.Map;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
import org.demo.ws.HelloWorld;

public class WsClient2
{
    /**
     * @param args
     */
    public static void main(String[] args)
    {
        String address = "http://localhost:8080/spring/services/hello";
        HelloWorld bean = getWebServiceClient(address, HelloWorld.class);
        String result = bean.sayHi("xiao ming");
        System.out.println("result is " + result);
    }
    
    /**
     * 创建 WebService 客户端
     * @param address      WebService address
     * @param serviceClass WebService interface
     * @return
     */
    public static <T>T getWebServiceClient(String address, Class<T> serviceClass)
    {
        JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
        factory.setAddress(address);
        factory.setServiceClass(serviceClass);
        
        Map<String, Object> props = new HashMap<String, Object>();
        props.put("action", "UsernameToken");
        props.put("passwordType", "PasswordText");
        props.put("user", "cxfClient");
        props.put("addUTElements", "Nonce Created");
        props.put("passwordCallbackRef", new ClientPasswordCallback());
        WSS4JOutInterceptor wSS4JOutInterceptor = new WSS4JOutInterceptor(props);
        factory.getOutInterceptors().add(wSS4JOutInterceptor);
        
        return factory.create(serviceClass);
    }
}

5. 发送的消息内容如下:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <wsse:Security
      xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
      xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
      soap:mustUnderstand="1">
      <wsse:UsernameToken wsu:Id="UsernameToken-1">
        <wsse:Username>user1</wsse:Username>
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password1</wsse:Password>
        <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">UGlQLI2CcjAyC7hLK3Akvg==</wsse:Nonce>
        <wsu:Created>2014-11-26T15:24:24.758Z</wsu:Created>
      </wsse:UsernameToken>
    </wsse:Security>
  </SOAP-ENV:Header>
  <soap:Body>
    <ns2:sayHi xmlns:ns2="http://ws.demo.org/">
      <arg0>xiao ming</arg0>
    </ns2:sayHi>
  </soap:Body>
</soap:Envelope>

// END

你可能感兴趣的:(CXF 发布WebService - 客户端调用)