Apache-cxf小结

一、简介

  Web service是一个平台独立的,低耦合的,自包含的、基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集)标准来描述、发布、发现、协调和配置这些应用程序,用于开发分布式的互操作的应用程序。

二、使用

  1、使用jdk的类发布webservice

    a、编写接口和实现类

package org.moy.soap.jdk;

import javax.jws.WebService;

/**
 * say something
 * @author <a href="moy25@foxmail.com">Ye Xiang Yang</a>
 * @since 1.0.0
 */
@WebService
public interface HelloService {

    String sayHi(String name);
}
View Code
package org.moy.soap.jdk;

import javax.jws.WebService;

/**
 * say something
 * @author <a href="moy25@foxmail.com">Ye Xiang Yang</a>
 * @since 1.0.0
 */
@WebService
public class HelloServiceImpl implements HelloService {

    @Override
    public String sayHi(String name) {
        return String.format("hi , %s" , name);
    }
}
View Code

    b、编写服务端和客户端

package org.moy.soap.jdk;

import javax.xml.ws.Endpoint;

/**
 * say something
 *
 * @author <a href="moy25@foxmail.com">Ye Xiang Yang</a>
 * @since 1.0.0
 */
public class SoapServer {

    public static void main(String[] args) {
        String soapAddress = "http://localhost:8080/ws/soap/hi";

        Endpoint.publish(soapAddress, new HelloServiceImpl());

        System.out.printf("WebService address : %s?wsdl", soapAddress);
    }
}
View Code
package org.moy.soap.jdk;

import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * say something
 *
 * @author <a href="moy25@foxmail.com">Ye Xiang Yang</a>
 * @since 1.0.0
 */
public class SoapClient {

    public static void main(String[] args) throws MalformedURLException {
        URL wsdl = new URL("http://localhost:8080/ws/soap/hi?wsdl");
        String targetNamespace = "http://jdk.soap.moy.org/";
        QName serviceName = new QName(targetNamespace, "HelloServiceImplService");
        QName portName = new QName(targetNamespace, "HelloServiceImplPort");
        Service service = Service.create(wsdl, serviceName);
        HelloService helloService = service.getPort(portName, HelloService.class);
        System.out.println(helloService.sayHi("moy"));
    }
}
View Code

    c、测试:运行服务后,在运行客户端

  2、使用cxf发布webservice

    a、新建好web工程,比如我使用maven新建工程,其pom.xml配置文件为

<?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">
    <parent>
        <artifactId>webservice-demo</artifactId>
        <groupId>org.moy.soap</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>soap-webapp</artifactId>
    <packaging>war</packaging>

    <name>soap-webapp Maven Webapp</name>
    <!-- FIXME change it to the project's website -->
    <url>http://www.example.com</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring.version>4.0.5.RELEASE</spring.version>
        <cxf.version>3.2.4</cxf.version>
    </properties>

    <dependencies>
        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- CXF -->
        <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-transports-http</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-ws-security</artifactId>
            <version>${cxf.version}</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>soap-webapp</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.7.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <port>8080</port>
                    <charset>${project.build.sourceEncoding}</charset>
                    <server>tomcat7</server>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
View Code

    b、编写接口和实现类

package org.moy.soap.service;

import javax.jws.WebService;

/**
 * say something
 *
 * @author <a href="moy25@foxmail.com">Ye Xiang Yang</a>
 * @since 1.0.0
 */
@WebService
public interface HelloService {

    String say(String name , String word);
}
View Code
package org.moy.soap.service;

import org.springframework.stereotype.Component;

import javax.jws.WebService;

/**
 * say something
 *
 * @author <a href="moy25@foxmail.com">Ye Xiang Yang</a>
 * @since 1.0.0
 */
@WebService
@Component
public class HelloServiceImpl implements HelloService{

    @Override
    public String say(String name, String word) {
        return String.format("%s : %s" , name ,word);
    }
}
View Code

    c、配置web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
         http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">

    <!-- Spring -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- CXF -->
    <servlet>
        <servlet-name>cxf</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>cxf</servlet-name>
        <url-pattern>/ws/*</url-pattern>
    </servlet-mapping>

</web-app>
View Code

    d、配置spring.xml和spring-cxf.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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <context:component-scan base-package="org.moy"/>

    <import resource="spring-cxf.xml"/>

</beans>
View Code
<?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-4.0.xsd
       http://cxf.apache.org/jaxws
       http://cxf.apache.org/schemas/jaxws.xsd">

    <jaxws:endpoint id="helloService" implementor="#helloServiceImpl" address="/soap/hello" />
</beans>
View Code

    e、编写调用webservice工具类SoapUtils

package org.moy.soap.utils;

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.endpoint.dynamic.DynamicClientFactory;
import org.apache.cxf.service.model.BindingInfo;
import org.apache.cxf.service.model.BindingOperationInfo;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;

import javax.xml.namespace.QName;
import java.util.Objects;

/**
 * say something
 *
 * @author <a href="moy25@foxmail.com">Ye Xiang Yang</a>
 * @since 1.0.0
 */
public class SoapUtils {
    private static DynamicClientFactory factory = DynamicClientFactory.newInstance();
    private static long DEFAULT_TIMEOUT = 3 * 60 * 1000;

    /**
     * 执行远程服务方法
     *
     * @param wsdl   wsdl地址
     * @param method 远程服务方法名
     * @param params 远程服务方法名
     * @return 返回值
     * @throws Exception 调用异常
     */
    public static Object invoke(String wsdl, String method, Object... params)
            throws Exception {

        return invoke(wsdl, method, DEFAULT_TIMEOUT, params);
    }

    /**
     * 执行远程服务方法
     *
     * @param wsdl    wsdl地址
     * @param method  远程服务方法名
     * @param timeout 等待时间
     * @param params  远程服务方法名
     * @return 返回值
     * @throws Exception 调用异常
     */
    public static Object invoke(String wsdl, String method, long timeout, Object... params)
            throws Exception {

        Client client = createClient(wsdl, timeout);
        return invokeByClient(client, method, params);
    }

    /**
     * 执行远程服务方法
     *
     * @param client org.apache.cxf.endpoint.Client
     * @param method 远程服务方法名
     * @param params 参数
     * @return 返回值
     * @throws Exception 调用异常
     */
    public static Object invokeByClient(Client client, String method, Object... params)
            throws Exception {

        QName operateQName = getOperateQName(client, method);

        Object[] result = client.invoke(operateQName, params);

        return result[0];
    }

    /**
     * 创建客户端
     *
     * @param wsdl wsdl地址
     * @return 客户端
     */
    public static Client createClient(String wsdl) {
        return createClient(wsdl, DEFAULT_TIMEOUT);
    }

    /**
     * 创建客户端
     *
     * @param wsdl    wsdl地址
     * @param timeout 请求等待时间
     * @return org.apache.cxf.endpoint.Client
     */
    public static Client createClient(String wsdl, long timeout) {

        validateWsdl(wsdl);

        Client client = factory.createClient(wsdl);

        setHttpConduit(client, timeout);

        return client;
    }

    private static void setHttpConduit(Client client, long timeout) {
        HTTPConduit conduit = (HTTPConduit) client.getConduit();
        HTTPClientPolicy policy = createHttpClientPolicy(timeout);
        conduit.setClient(policy);
    }

    private static HTTPClientPolicy createHttpClientPolicy(long timeout) {
        HTTPClientPolicy policy = new HTTPClientPolicy();
        policy.setAllowChunking(Boolean.FALSE);
        policy.setConnectionTimeout(timeout);
        policy.setReceiveTimeout(timeout);
        return policy;
    }

    /**
     * 校验wsdl合法性
     *
     * @param wsdl wsdl地址
     */
    private static void validateWsdl(String wsdl) {
        if (Objects.isNull(wsdl) || wsdl.length() < 5) {
            throw new IllegalArgumentException(String.format("[%s]所对应的webService地址不合法!", wsdl));
        }
    }

    /**
     * 针对SEI和SIB不在统一个包内的情况,
     * 先查找操作对应的QName,client通过QName调用对应操作
     *
     * @param client    客户端
     * @param operation 方法名
     * @return QName
     */
    private static QName getOperateQName(Client client, String operation) {
        Endpoint endpoint = client.getEndpoint();
        String namespaceURI = endpoint.getService().getName().getNamespaceURI();
        QName opName = new QName(namespaceURI, operation);
        BindingInfo bindingInfo = endpoint.getEndpointInfo().getBinding();
        BindingOperationInfo bindingInfoOperation = bindingInfo.getOperation(opName);
        if (Objects.isNull(bindingInfoOperation)) {
            for (BindingOperationInfo operationInfo : bindingInfo.getOperations()) {
                if (operation.equals(operationInfo.getName().getLocalPart())) {
                    opName = operationInfo.getName();
                    break;
                }
            }
        }
        return opName;
    }
}
View Code

    f、使用maven运行tomcat7插件编写测试类App

package org.moy.soap.service;

import org.moy.soap.utils.SoapUtils;

/**
 * say something
 *
 * @author <a href="moy25@foxmail.com">Ye Xiang Yang</a>
 * @since 1.0.0
 */
public class App {

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

        String address = "http://localhost:8080/soap-webapp/ws/soap/hello?wsdl";

        Object result = SoapUtils.invoke(address, "say", "moy", "hi");

        System.out.println(result);
    }
}
View Code

三、总结

  新的项目基本很少会用webservice了,还是记录一下,免得以后忘了。

yexiangyang

moyyexy@gmail.com


 

posted @ 2018-06-02 11:07  墨阳  阅读(488)  评论(0编辑  收藏  举报