上一篇文章,大概讲述了Apache Camel集成CXF(WebService)的使用方法。
担心有的童鞋看的不是很明白,我这里,详细的写一下。
因为没有现成的参考代码或参考Demo,如果我写的有不对的地方,烦请指正。
这里我将服务端、客户端测试代码上传了,有兴趣的童鞋,可以下载下来,写写看...
05-ApacheCamel-CXF-WebService 代码Demo样例
Apache Camel相关代码已经上传GitHub,需要的自取:GitHub - Apache Camel 完整Demo
如果觉得还行,麻烦点个Star
因为Apache Camel CXF基于WSDL文档发布WebService,在我们还不能熟练编写WSDL文档时,怎么获得WSDL文档呢?
我们可以用普通发布WebService的方法,来获得一个WSDL文档。
我们看下工程结构:
lib目录下是Apache CXF的jar包....
QueryServiceInter.java这个是WebService接口
package org.service.query;
import javax.jws.WebParam;
import javax.jws.WebService;
@WebService
public interface QueryServiceInter {
/**
* 查询人员信息
*
* @param queryInfo
* @return
*/
String queryPersonnelInformation(@WebParam(name = "peopleParam") String peopleParam);
/**
* 查询车辆信息
*
* @param carInfo
* @return
*/
String queryCarInfomation(@WebParam(name = "carParam") String carParam);
}
QueryService.java 接口实现类
package org.service.query;
import javax.jws.WebService;
@WebService
public class QueryService implements QueryServiceInter {
@Override
public String queryPersonnelInformation(String peopleParam) {
String returnRusult = "";
return returnRusult;
}
@Override
public String queryCarInfomation(String carParam) {
String returnRusult = "";
return returnRusult;
}
}
QueryServiceMain.java 发布主类
package org.service.query;
import org.apache.cxf.endpoint.Server;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
public class QueryServiceMain {
public static void main(String[] args) {
String address = "http://localhost:9098/service/queryInfo";
JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
factory.setServiceClass(QueryService.class); // 接口实现类
factory.setAddress(address);
factory.setServiceBean(new QueryService()); // 接口实现类
Server server = factory.create();
server.start();
System.out.println("CXF发布成功,address : " + address + "?wsdl");
}
}
我们启动程序,然后在浏览器中输入address:http://localhost:9098/service/queryInfo?wsdl
然后将这些内容,保存到本地,queryInfo.wsdl
<?xml version='1.0' encoding='UTF-8'?>
<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://query.service.org/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http"
name="QueryServiceService" targetNamespace="http://query.service.org/">
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://query.service.org/" elementFormDefault="unqualified"
targetNamespace="http://query.service.org/" version="1.0">
<xs:element name="queryCarInfomation" type="tns:queryCarInfomation" />
<xs:element name="queryCarInfomationResponse" type="tns:queryCarInfomationResponse" />
<xs:element name="queryPersonnelInformation" type="tns:queryPersonnelInformation" />
<xs:element name="queryPersonnelInformationResponse" type="tns:queryPersonnelInformationResponse" />
<xs:complexType name="queryCarInfomation">
<xs:sequence>
<xs:element minOccurs="0" name="carParam" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="queryCarInfomationResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="queryPersonnelInformation">
<xs:sequence>
<xs:element minOccurs="0" name="peopleParam" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="queryPersonnelInformationResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:schema>
</wsdl:types>
<wsdl:message name="queryCarInfomation">
<wsdl:part element="tns:queryCarInfomation" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="queryCarInfomationResponse">
<wsdl:part element="tns:queryCarInfomationResponse" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="queryPersonnelInformation">
<wsdl:part element="tns:queryPersonnelInformation" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="queryPersonnelInformationResponse">
<wsdl:part element="tns:queryPersonnelInformationResponse"
name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:portType name="QueryServiceInter">
<wsdl:operation name="queryCarInfomation">
<wsdl:input message="tns:queryCarInfomation" name="queryCarInfomation">
</wsdl:input>
<wsdl:output message="tns:queryCarInfomationResponse"
name="queryCarInfomationResponse">
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="queryPersonnelInformation">
<wsdl:input message="tns:queryPersonnelInformation" name="queryPersonnelInformation">
</wsdl:input>
<wsdl:output message="tns:queryPersonnelInformationResponse"
name="queryPersonnelInformationResponse">
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="QueryServiceServiceSoapBinding" type="tns:QueryServiceInter">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="queryCarInfomation">
<soap:operation soapAction="" style="document" />
<wsdl:input name="queryCarInfomation">
<soap:body use="literal" />
</wsdl:input>
<wsdl:output name="queryCarInfomationResponse">
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="queryPersonnelInformation">
<soap:operation soapAction="" style="document" />
<wsdl:input name="queryPersonnelInformation">
<soap:body use="literal" />
</wsdl:input>
<wsdl:output name="queryPersonnelInformationResponse">
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="QueryServiceService">
<wsdl:port binding="tns:QueryServiceServiceSoapBinding"
name="QueryServicePort">
<soap:address location="http://localhost:9098/service/queryInfo" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
以上,我们首先获得了一个WSDL文档。
我们将wsdl文档,放在桌面,上面那个工程可以关闭了,下面的代码,和上面的工程没有任何关系了...
创建一个Apache Camel 的Maven工程
看下工程结构:
我们进入从cmd命令行,然后进入到工程-src/main/java目录下,输入如下命令:
CXF根据WSDL文档,帮我们自动生成了服务端、接口代码
自动生成的代码中,我们只要留下接口和接口实现类,其他的全部删除....
然后我们修改一下
QueryServiceInter.java
package org.service.query;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;
/**
* This class was generated by Apache CXF 3.1.7 2018-02-02T12:34:20.911+08:00
* Generated source version: 3.1.7
*
*/
@WebService(targetNamespace = "http://query.service.org/", name = "QueryServiceInter")
public interface QueryServiceInter {
@WebMethod
@RequestWrapper(localName = "queryCarInfomation", targetNamespace = "http://query.service.org/", className = "org.service.query.QueryCarInfomation")
@ResponseWrapper(localName = "queryCarInfomationResponse", targetNamespace = "http://query.service.org/", className = "org.service.query.QueryCarInfomationResponse")
@WebResult(name = "return", targetNamespace = "")
public java.lang.String queryCarInfomation(
@WebParam(name = "carParam", targetNamespace = "") java.lang.String carParam);
@WebMethod
@RequestWrapper(localName = "queryPersonnelInformation", targetNamespace = "http://query.service.org/", className = "org.service.query.QueryPersonnelInformation")
@ResponseWrapper(localName = "queryPersonnelInformationResponse", targetNamespace = "http://query.service.org/", className = "org.service.query.QueryPersonnelInformationResponse")
@WebResult(name = "return", targetNamespace = "")
public java.lang.String queryPersonnelInformation(
@WebParam(name = "peopleParam", targetNamespace = "") java.lang.String peopleParam);
}
QueryServicePortImpl.java 接口实现类
/**
* Please modify this class to meet your needs
* This class is not complete
*/
package org.service.query;
import org.apache.log4j.Logger;
/**
* This class was generated by Apache CXF 3.1.7 2018-02-02T12:34:20.850+08:00
* Generated source version: 3.1.7
*
*/
// @javax.jws.WebService(serviceName = "QueryServiceService", portName =
// "QueryServicePort", targetNamespace = "http://query.service.org/",
// wsdlLocation = "file:/C:/Users/CYX/Desktop/queryInfo.wsdl", endpointInterface
// = "org.service.query.QueryServiceInter")
public class QueryServicePortImpl implements QueryServiceInter {
public static final Logger logger = Logger.getLogger(QueryServicePortImpl.class);
public java.lang.String queryCarInfomation(java.lang.String carParam) {
logger.info("Executing operation queryCarInfomation");
System.out.println(carParam);
try {
java.lang.String _return = "";
return _return + "123456";
} catch (java.lang.Exception ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
}
public java.lang.String queryPersonnelInformation(java.lang.String peopleParam) {
logger.info("Executing operation queryPersonnelInformation");
System.out.println(peopleParam);
try {
java.lang.String _return = "";
return _return + "987654321";
} catch (java.lang.Exception ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
}
}
下面我们编写Camel内部发布的WebService,
QueryServiceServer.java
package org.service.query.server;
import javax.xml.ws.Endpoint;
import org.apache.log4j.Logger;
import org.service.query.QueryServicePortImpl;
import com.camel.webservice.server.CamelReleaseServerMain;
public class QueryServiceServer {
public static final Logger logger = Logger.getLogger(QueryServiceServer.class);
public void internalQueryService() throws Exception {
String address = CamelReleaseServerMain.SERVICE_ADDRESS;
Endpoint.publish(address, new QueryServicePortImpl());
logger.info("Camel 内部 WebService 发布成功 , address : " + address);
}
}
对了,别忘记了,把WSDL文档,放在工程的目录下面
下面我们看下Camel WebService 发布的主类:
CamelReleaseServerMain.java
package com.camel.webservice.server;
import org.apache.camel.CamelContext;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.cxf.CxfComponent;
import org.apache.camel.component.cxf.CxfEndpoint;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.service.query.QueryServiceInter;
import org.service.query.server.QueryServiceServer;
public class CamelReleaseServerMain {
public static final Logger logger = Logger.getLogger(CamelReleaseServerMain.class);
// Apache Camel 路由对外发布的WebService URL
private static final String ROUTER_ADDRESS = "http://localhost:9080/server/queryservice";
// Apache Camel 内部发布的WebService URL
public static final String SERVICE_ADDRESS = "http://localhost:9010/server/queryservice";
// WebService 接口全类名
private static final String SERVICE_CLASS = "serviceClass=org.service.query.QueryServiceInter";
// WSDL文档地址
private static final String WSDL_LOCATION = "wsdlURL=wsdl/queryInfo.wsdl";
// Apache Camel 路由路径
private static final String ROUTER_ENDPOINT_URI = "cxf://" + ROUTER_ADDRESS + "?" + SERVICE_CLASS + "&"
+ WSDL_LOCATION + "&dataFormat=POJO";
public static void main(String[] args) {
// 日志
PropertyConfigurator.configure("./conf/log4j.properties");
PropertyConfigurator.configureAndWatch("./conf/log4j.properties", 1000);
// Camel 上下文
CamelContext context = new DefaultCamelContext();
try {
// 内部WebService启动
QueryServiceServer queryServiceServer = new QueryServiceServer();
queryServiceServer.internalQueryService();
// Camel 添加WebService 路由
context.addRoutes(new RouteBuilder() {
@Override
public void configure() throws Exception {
CxfComponent cxfComponent = new CxfComponent(getContext());
CxfEndpoint serviceEndpoint = new CxfEndpoint(SERVICE_ADDRESS, cxfComponent);
serviceEndpoint.setServiceClass(QueryServiceInter.class);
from(ROUTER_ENDPOINT_URI).to("log:CamelReleaseServerMain?showExchangeId=true").to(serviceEndpoint);
}
});
logger.info("Camel 外部 WebService : " + ROUTER_ADDRESS);
context.start();
// 通用没有具体业务意义的代码,只是为了保证主线程不退出
synchronized (CamelReleaseServerMain.class) {
CamelReleaseServerMain.class.wait();
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
}
然后我们启动程序
然后我们,在浏览器中访问:http://localhost:9080/server/queryservice?wsdl
没问题的话,可以在浏览器中看到WSDL文档....
接着我们创建一个客户端工程进行测试
生成客户端代码:
编写客户端测试代码:
package com.test.client;
import java.net.URL;
import org.service.query.QueryServiceInter;
import org.service.query.QueryServiceService;
public class TestClient {
public static void main(String[] args) throws Exception {
URL url = new URL("http://localhost:9080/server/queryservice?wsdl");
QueryServiceService queryServiceService = new QueryServiceService(url);
QueryServiceInter queryServiceInter = queryServiceService.getQueryServicePort();
String carInfoStr = queryServiceInter.queryCarInfomation("宝马");
String personStr = queryServiceInter.queryPersonnelInformation("马云");
System.out.println(carInfoStr);
System.out.println(personStr);
}
}
服务端控制台日志打印:
客户端打印日志:
没问题了吧......