Apache Camel - 25 - CXF - WebService(Code First)

本篇文章对应的完整项目源码地址:

15-ApacheCamel-CXF-Demo-Server(Code First)

16-ApacheCamel-CXF-Demo

_16-ApacheCamel-CXF-Demo-Client

"15-ApacheCamel-CXF-Demo-Server(Code First)" 是参照官方Demo例子写的:https://github.com/apache/camel/tree/master/examples/camel-example-cxf

"16-ApacheCamel-CXF-Demo" 是根据日常最简原则写的Demo。

 

Apache Camel 相关所有Demo代码,已上传GitHub,需要的请自取:GitHub - Apache Camel 完整Demo

如果觉得还不错,请点star

 

前言

首先假定,你是使用过Apache CXF 或者 WebService的,如不了解,请先移步 WebService(Apache CXF)分享

如果你之前看过Apache Camel 集成 CXF的前两篇:

Apache Camel - 14 - CXF组件Apache Camel - 15 - CXF组件(2)

你会发现,其中的Demo样例,都是基于WSDL文件来发布WebService的。

因为在此之前,没有在官方Demo中找到,也有可能是我看走眼了没有发现(心塞...)。

言归正传,下面看下基于代码优先方式发布WebService

 

 

Apache Camel 集成 Apache CXF 发布WebService,基于代码优先的方式

这里先介绍下WebService(CXF)服务端发布的两种方式:基于WSDL方式 和 纯代码方式

  • 基于WSDL方式:这种方式一般情况是第三方给你一个WSDL文档,然后你根据这个WSDL文档生成服务端代码,JDK原生的我并没有试过,我之前用的都是CXF的命令方式生成的服务端代码,然后在开发业务代码,启动服务端,发布WebService
  • 纯代码方式:这种方式是最原始的方式,也是字面意思,只要你写过WebService,就一定能理解,参考:WebService(3)_开发流程(原生/JDK自带工具)

Apache Camel 集成 CXF 也是可以用以上两种方式来发布WebService,可惜之前我只找到基于WSDL的,可能是我英文不好,错过了。

下面看下关键代码:

pom.xml

<!--apache camel-->
        <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-core</artifactId>
            <version>2.22.0</version>
        </dependency>

        <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-jetty</artifactId>
            <version>2.22.0</version>
        </dependency>

        <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-cxf</artifactId>
            <version>2.22.0</version>
        </dependency>

        <!--apache cxf-->
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http-jetty</artifactId>
            <version>3.2.5</version>
        </dependency>

        <!--logback-->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.2.3</version>
        </dependency>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-access</artifactId>
            <version>1.2.3</version>
        </dependency>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>

        <!--apache commons-->
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.7</version>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-collections4</artifactId>
            <version>4.1</version>
        </dependency>

        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <version>3.2.2</version>
        </dependency>

        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>

发布的接口,就像开发普通WebService一样,添加@WebService以及@WebMethod注解

package com.server.service;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;

/**
 * @author CYX
 * @create 2018-12-27-19:59
 */
@WebService
public interface BaseicQuery {

    /**
     * 查询人员信息
     *
     * @param queryCondition 基础查询
     * @return
     */
    @WebMethod
    String queryPeopleInfo(@WebParam(name = "queryCondition") String queryCondition);

}

发布接口的实现类

package com.server.service.impl;

import com.server.service.BaseicQuery;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author CYX
 * @create 2018-12-27-20:00
 */
public class BaseicQueryImpl implements BaseicQuery {

    private static final Logger LOGGER = LoggerFactory.getLogger(BaseicQueryImpl.class);

    @Override
    public String queryPeopleInfo(String queryCondition) {

        LOGGER.info("queryCondition : " + queryCondition);

        return "copy that";
    }
}

路由的process处理类:

package com.server.process;

import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.component.cxf.common.message.CxfConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;

/**
 * @author CYX
 * @create 2018-12-27-20:36
 */
public class BaseicQueryProcess implements Processor {

    private static final Logger LOGGER = LoggerFactory.getLogger(BaseicQueryProcess.class);

    private Class<?> beanClass;
    private Object instance;

    public BaseicQueryProcess(Object object) {
        beanClass = object.getClass();
        instance = object;
    }

    @Override
    public void process(Exchange exchange) throws Exception {

        String inputMessage = exchange.getIn().getBody(String.class);
        LOGGER.info("inputMessage : " + inputMessage);

        String operationName = exchange.getIn().getHeader(CxfConstants.OPERATION_NAME, String.class);
        Method method = findMethod(operationName, exchange.getIn().getBody(Object[].class));

        Object response = method.invoke(instance, exchange.getIn().getBody(Object[].class));

        exchange.getOut().setBody(response);
    }

    private Method findMethod(String operationName, Object[] parameters) throws SecurityException, NoSuchMethodException {
        return beanClass.getMethod(operationName, getParameterTypes(parameters));
    }

    private Class<?>[] getParameterTypes(Object[] parameters) {

        if (parameters == null) {
            return new Class[0];
        }
        Class<?>[] answer = new Class[parameters.length];
        int i = 0;
        for (Object object : parameters) {
            answer[i] = object.getClass();
            i++;
        }
        return answer;
    }

}

这个类是关键,它通过反射来调用接口实现类中的方法,仔细看。

路由类:

package com.server.route;

import com.server.App;
import com.server.process.BaseicQueryProcess;
import com.server.service.impl.BaseicQueryImpl;
import org.apache.camel.builder.RouteBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author CYX
 * @create 2018-12-27-20:05
 */
public class BaseQueryRoute extends RouteBuilder {

    private static final Logger LOGGER = LoggerFactory.getLogger(BaseQueryRoute.class);

    @Override
    public void configure() throws Exception {

        from(App.BASEQUERY_SERVICE_URL_ADDRESS).process(new BaseicQueryProcess(new BaseicQueryImpl()));

    }
}

将接口实现类传到process 构造函数中。

主类:

package com.server;

import com.server.conf.LogBackConfigLoader;
import com.server.route.BaseQueryRoute;
import org.apache.camel.CamelContext;
import org.apache.camel.impl.DefaultCamelContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Apache Camel With CXF-JAXRS(Code First)
 * <p>
 * Apache Camel集成Apache CXF-JAXRS,发布WebService(代码优先)
 *
 * @author CYX
 */
public class App {

    private static final Logger LOGGER = LoggerFactory.getLogger(App.class);

    private static final String LOGBACK_FILENAME = "./conf/logback.xml";

    public static final String BASEICQUERY_SERVICE_URL = "http://localhost:9999/baseQueryService";

    public static final String BASEQUERY_SERVICE_URL_ADDRESS = "cxf://" + BASEICQUERY_SERVICE_URL + "?serviceClass=com.server.service.BaseicQuery";

    public static void main(String[] args) {

        try {

            LogBackConfigLoader.loadLogBack(LOGBACK_FILENAME);

            CamelContext camelContext = new DefaultCamelContext();
            camelContext.start();
            camelContext.addRoutes(new BaseQueryRoute());

            LOGGER.info("baseic query service address : " + BASEICQUERY_SERVICE_URL + "?wsdl");

        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
        }

    }
}

主类 启动类 没啥好解释的吧。

以上Demo中,最关键的是process处理类,没有这层调用关系,就没法调用到接口实现类,这个需要注意。

 

看下Demo启动测试,启动服务端:

看下WSDL文档:

然后我们用标准流程生成 Client 客户端代码,调用测试一下:

/**
 * Hello world!
 */
public class ClientApp {

    public static void main(String[] args) {

        BaseicQueryService baseicQueryService = new BaseicQueryService();
        BaseicQuery baseicQuery = baseicQueryService.getBaseicQueryPort();
        String resultMessage = baseicQuery.queryPeopleInfo("server , do you copy");
        System.out.println(resultMessage);

    }

}

 

服务端日志:

客户端接收日志:

 

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值