新建一个WebService项目
目录结构
配置tomcat
访问 http://localhost:8080/test_webservice/
说明项目启动成功
生成
注意这里要修改成 tomcat配置的访问ip
修改后的 http://localhost:8080/test_webservice/services/HelloWorld
点击OK生成
添加必要的jar包
设置一下
访问 http://localhost:8080/test_webservice/services
springboot 如何调用webservice接口
引入依赖
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.1.4</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.1.4</version>
</dependency>
import cn.hutool.core.lang.Console;
import cn.hutool.core.thread.ConcurrencyTester;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import java.util.concurrent.ConcurrentHashMap;
public class WebServiceClientFactory {
// 1. 重用工厂实例,避免重复初始化开销
private static final JaxWsDynamicClientFactory CLIENT_FACTORY = JaxWsDynamicClientFactory.newInstance();
// 2. 缓存客户端实例(按 WSDL 地址缓存)
private static final ConcurrentHashMap<String, Client> CLIENT_CACHE = new ConcurrentHashMap<>();
// 3. 可配置参数(默认值可通过系统属性或配置文件覆盖)
private static final int DEFAULT_CONN_TIMEOUT = Integer.getInteger("ws.connection.timeout", 10_000);
private static final int DEFAULT_RECEIVE_TIMEOUT = Integer.getInteger("ws.receive.timeout", 180_000);
// 4. 双重校验锁获取客户端
public static Client getClient(String wsdl) throws ServiceConstructionException {
Client client = CLIENT_CACHE.get(wsdl);
if (client == null) {
synchronized (WebServiceClientFactory.class) {
client = CLIENT_CACHE.get(wsdl);
if (client == null) {
client = createNewClient(wsdl);
CLIENT_CACHE.put(wsdl, client);
}
}
}
return client;
}
// 5. 解耦客户端创建逻辑
private static Client createNewClient(String wsdl) throws ServiceConstructionException {
try {
Client client = CLIENT_FACTORY.createClient(wsdl);
configureHttpPolicy(client);
return client;
} catch (Exception e) {
throw new ServiceConstructionException("Failed to create client for WSDL: " + wsdl, e);
}
}
// 6. 配置方法支持自定义超时
private static void configureHttpPolicy(Client client) {
try {
HTTPConduit conduit = (HTTPConduit) client.getConduit();
HTTPClientPolicy policy = new HTTPClientPolicy();
policy.setConnectionTimeout(DEFAULT_CONN_TIMEOUT);
policy.setReceiveTimeout(DEFAULT_RECEIVE_TIMEOUT);
conduit.setClient(policy);
} catch (ClassCastException e) {
// 7. 处理不支持的通信协议类型
throw new UnsupportedTransportException("Only HTTP transport is supported", e);
}
}
// 8. 提供清理缓存的入口
public static void cleanupCache(String wsdl) {
Client client = CLIENT_CACHE.remove(wsdl);
if (client != null) {
cleanupClient(client);
}
}
// 9. 资源清理方法
private static void cleanupClient(Client client) {
try {
client.destroy();
} catch (Exception e) {
// 10. 异常处理及日志记录
//Logger.error("Error destroying client", e);
}
}
// 自定义异常类(可根据需要细化)
public static class ServiceConstructionException extends Exception {
public ServiceConstructionException(String message, Throwable cause) {
super(message, cause);
}
}
public static class UnsupportedTransportException extends RuntimeException {
public UnsupportedTransportException(String message, Throwable cause) {
super(message, cause);
}
}
public static void main(String[] args) {
ConcurrencyTester tester = ThreadUtil.concurrencyTest(10, () -> {
// 测试的逻辑内容
long delay = RandomUtil.randomLong(100, 1000);
String operationName = "sayHelloWorldFrom";
// 获取客户端
try {
Client client = WebServiceClientFactory.getClient("http://localhost:8080/test_webservice/services/HelloWorld?wsdl");
String format = StrUtil.format("{} {} test finished, delay: {}", client.hashCode(), Thread.currentThread().getName(), delay);
Console.log(format);
// 使用客户端进行调用...
Object[] response = client.invoke(operationName, format);
String guid = response[0].toString();
System.out.println(guid);
} catch (WebServiceClientFactory.ServiceConstructionException e) {
// 处理客户端创建失败异常
} catch (Exception e) {
// 处理客户端创建失败异常
}finally {
// 根据业务需要决定是否立即清理(通常长连接推荐缓存复用)
// WebServiceClientFactory.cleanupCache(wsdl);
}
});
}
}
经测试,在createClient操作中,会生产webservice下所有方法类、参数类、返回值类等等文件,耗时相当惊人,超级慢,后来想要需要优化创建初始化步骤;
后来从博友http://ruijf.iteye.com/blog/1186961上看到创建的client是线性安全,正好是自己所想要的效果;
Web Service 缺点:性能开销大、协议复杂、不适合实时或高频大数据场景。