=======
在 Axis1 中的全局配置和 Servcies 的配置均在 server-config.wsdd 中进行配置,而 Axis2则将全局配置单独存放于 WEB-INF/conf/axis2.xml 中, services 的配置文件则位于 servcies。
发布服务(Publish Service)
=====================
新建一个 HelloService 类并编译为 HelloService.class 复制至 WEB-INF/pojo 目录下并重启服务。
// 不能声明package
public class HelloService {
public HelloService(){}
public String sayHello() {
return “hello”;
}
public String sayHelloToPerson(String name) {
if (name == null) {
name = “nobody”;
}
return "hello, " + name;
}
}
重启服务后再次访问
http://localhost:8080/Axis2Demo_war_exploded/services/HelloService?wsdl 即可发现新发布的服务,点击 HelloService 即可查看Axis自动为该服务生成的WSDL,其描述了如何调用服务的方法及返回内容:
使用 SoapUI 客户端调用 HelloService 服务方法:
而之所以 WEB-INF/pojo 目录下的 .class 文件会自动发布为服务是因为在 axis2.xml 配置文件中的 deployer 标签中所配置的该选项。
上述的方式发布服务需要将编译后的类放置在某个具体的目录中,且不能包含 package ,而使用 *.aar 的方式则可以解决此问题。首先在Project的根目录下新建 META-INF/services.xml ,文件内容可以参考官方示例 version.aar 。
<?xml version="1.0" encoding="UTF-8"?>一个简单的WebService
com.ws.test.services.HelloService
<messageReceiver mep=“http://www.w3.org/ns/wsdl/in-only”
class=“org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver” />
<messageReceiver mep=“http://www.w3.org/2004/08/wsdl/in-out”
class=“org.apache.axis2.rpc.receivers.RPCMessageReceiver” />
最终结构为如下所示,在项目根目录中执行 jar cvf HelloService.aar . 进行打包。
将打包后的文件复制至 WEB-INF/services 目录下,即可在服务列表中看到新注册的服务,或者在 Axis 后台中也可以上传包部署(因此如果应用程序的Axis后台可访问且为默认凭据即可部署恶意Service获取权限)。
客户端服务调用
=======
调用 Web Service 可通过代码的方式实现也可以通过WSDL构造SOAP协议调用方法,最简便的方法则是使用SoapUI,其会根据 Web Service 的WSDL生成对应方法的SOAP协议请求。
// 代码实现Web Service调用
import javax.xml.namespace.QName;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient;
public class WebServiceClient {
public static void main(String[] args) throws Exception {
RPCServiceClient serviceClient = new RPCServiceClient();
Options options = serviceClient.getOptions();
EndpointReference targetEPR = new EndpointReference(“http://192.168.0.105:8080/Axis2Demo_war_exploded/services/HelloService”);
options.setTo(targetEPR);
Object[] entryArgs = new Object[]{4, 2};
QName qName = new QName(“http://ws.apache.org/axis2”, “add”);
Object result = serviceClient.invokeBlocking(qName, entryArgs, new Class[]{int.class})[0];
qName = new QName(“http://ws.apache.org/axis2”, “send”);
serviceClient.invokeRobust(qName, new Object[]{“hello world!”});
}
}
Soap UI
Apache CXF
==========
Apache CXF是一个开源的、全功能的,容易使用的Web服务框架。CXF是两个项目的结合:由IONA技术公司开发的Celtix和由Codehaus主持的团队开发的XFire。
CXF支持的特性非常广泛,但特性主要在以下一些方面:
-
支持的Web服务标准包括: SOAP WS-Addressing WS-Policy WS-ReliableMessaging WS-Security WS-SecurityPolicy WS-SecureConversation
-
JAS-WS API,用于Web服务开发 WSDL优先支持工具 Java优先支持
-
JAX-RS(JSR 311 1.0)API,用于RESTful Web服务开发
-
…
⬆️内容摘自Wiki百科。
发布服务
====
使用 Maven 构建项目,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”>
4.0.0
org.example
CXFDemo
1.0-SNAPSHOT
org.apache.cxf
cxf-rt-frontend-jaxws
3.4.0
org.apache.cxf
cxf-rt-transports-http
3.4.0
org.apache.cxf
cxf-rt-transports-http-jetty
3.4.0
org.apache.cxf
cxf-rt-transports-http-jetty
3.4.0
编写一个服务接口,定义 sayHi 方法:
package org.example.services;
import javax.jws.WebService;
// 声明这是一个Ws服务接口
@WebService
public interface HelloWorld {
// 定义服务方法
String sayHi(String name);
}
编写一个服务接口的实现类:
package org.example.services;
import javax.jws.WebService;
@WebService(endpointInterface = “org.example.services.HelloWorld”, serviceName = “HelloWorld”)
public class HelloWorldImpl implements HelloWorld {
public String sayHi(String name) {
return "hi, " + name;
}
}
再编写一个发布服务的主类 Main :
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
import org.example.services.HelloWorld;
import org.example.services.HelloWorldImpl;
public class Main {
public static void main(String[] args) {
HelloWorldImpl implementor = new HelloWorldImpl();
JaxWsServerFactoryBean svrFactory = new JaxWsServerFactoryBean();
svrFactory.setServiceClass(HelloWorld.class);
svrFactory.setAddress(“http://localhost:9000/helloworld”);
svrFactory.setServiceBean(implementor);
svrFactory.create();
}
}
运行后即可访问
http://localhost:9000/helloworld?wsdl 查看该服务,从WSDL的描述文件中也能看出 HelloWorld 服务提供了 sayHi 方法,且该方法需要一个字符串参数,返回值也为字符串。
使用 SoapUI 调用该方法示例:
通过代码也可以实现客户端调用 Web Service :
import org.example.services.HelloWorld;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import javax.xml.ws.soap.SOAPBinding;
public class WsClient {
private static final QName SERVICE_NAME = new QName(“http://services.example.org/”, “HelloWorld”);
private static final QName PORT_NAME = new QName(“http://services.example.org/”, “HelloWorldPort”);
public static void main(String[] args) {
Service service = Service.create(SERVICE_NAME);
String endpointAddress = “http://localhost:9000/helloworld”;
service.addPort(PORT_NAME, SOAPBinding.SOAP11HTTP_BINDING, endpointAddress);
HelloWorld helloWorld = service.getPort(HelloWorld.class);
System.out.println(helloWorld.sayHi(“SearchNull”));
}
}
Spring整合CXF
===========
在Spring框架中可以集合 Apache CXF 框架发布 Web Service 服务,通过 Maven 或其他方式将CXF所需的Jar包导入项目中,编写 Web Service 接口及实现类即可。
package org.example.webservices;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
/**
-
@WebService注解标记一个webservice接口
-
@param targetNamespace 指定命名空间,默认使用包名的反转.
-
@param serviceName 对外发布的服务名称
-
@param portName wsdl:portName,默认为服务名 + Port
*/