一、服务端
1、配置pom依赖
<!--webService-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
<version>3.2.7</version>
</dependency>
2、自定义自动发布客户端注解
package com.bw.integrator.config.webSerivce;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 自定义的自动发布客户端注解(通过该注解,就知道要发布哪些服务端接口了)
* @author Duke <br/>
* @version 1.0
* @since JDK:1.8
*/
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoPublish {
/**
* 发布地址
* @author liuyu
* @return
*/
String publishAddr();
}
package com.bw.integrator.config.webSerivce;
import com.bw.integrator.service.SyncClientService;
import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;
/**
* @author Duke
* @version [版本号, 2021/06/29 12:02]
*/
@Component
public class PublishEndpoint implements ApplicationRunner {
private static final Logger LOGGER = LoggerFactory.getLogger(PublishEndpoint.class);
@Autowired
private WebApplicationContext webApplicationConnect;
@Autowired()
@Qualifier(Bus.DEFAULT_BUS_ID)
private SpringBus bus;
@SuppressWarnings("resource")
@Override
public void run(ApplicationArguments applicationArguments) throws Exception {
//当把应用打成一个jar包运行的时候,后面跟着的命令行参数可以通过ApplicationArguments拿到
LOGGER.info("开始进行自动发布web service接口");
String[] beanNames = webApplicationConnect.getBeanNamesForAnnotation(AutoPublish.class);
for(String beanName : beanNames) {
String publishAddr = webApplicationConnect.getType(beanName).getAnnotation(AutoPublish.class).publishAddr();
EndpointImpl endpointImpl = new EndpointImpl(bus, webApplicationConnect.getBean(beanName));
endpointImpl.publish(publishAddr);
LOGGER.info(String.format("发布的接口地址:[%s]", publishAddr));
}
LOGGER.info("完成web service接口自动发布");
}
}
3、配置cxf服务发布
package com.bw.integrator.config.webSerivce;
import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.feature.LoggingFeature;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 配置cxf服务发布,默认服务在Host:port/services/***路径下
*
* @author Duke
* @version [版本号, 2021/06/29 11:18]
*/
@Configuration
public class CxfConfig {
// @Autowired
// private Bus bus;
//
// @Autowired
// DispatchService dispatchService;
//
//
// /** JAX-WS **/
// @Bean
// public Endpoint endpoint(){
// EndpointImpl endpoint = new EndpointImpl(bus,dispatchService);
// endpoint.publish("/DispatchService");
// return endpoint;
// }
@Bean(name = Bus.DEFAULT_BUS_ID)
public SpringBus springBus() {
SpringBus bus = new SpringBus();
bus.getFeatures().add(new LoggingFeature());
return bus;
}
}
4、修改cxf发布地址
在application.properties里配置
#修改cxf发布地址,默认为Host:port/services/***;修改后为Host:port/ws/***
cxf.path=/ws
5、接口编写
package com.bw.integrator.service;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
/**
* @author Duke
*/
@WebService(name = "DispatchService",// 暴露服务名称
targetNamespace = "http://service.integrator.bw.com"// 命名空间,一般是接口的包名倒序
)
public interface DispatchService {
/**
* 设备模型获取接口
* @param getDeviceInfo
* @return
*/
@WebMethod
@WebResult(name = "String",targetNamespace = "")
String getDeviceInfoRequest(@WebParam(name = "getDeviceInfo") String getDeviceInfo);
}
package com.bw.integrator.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.bw.integrator.config.webSerivce.AutoPublish;
import com.bw.integrator.entity.vo.DeviceInfoEntity;
import com.bw.integrator.entity.vo.FileInfoEntity;
import com.bw.integrator.entity.vo.MarketClearingEntity;
import com.bw.integrator.entity.vo.WebServiceResult;
import com.bw.integrator.service.DispatchService;
import com.bw.integrator.util.FileUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Component;
import javax.jws.WebService;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* @author Duke
* Description: 基于jdk1.6以上的javax.jws 发布webservice接口
* @WebService - 它是一个注解,用在类上指定将此类发布成一个ws。
* Endpoint – 此类为端点服务类,它的方法publish用于将一个已经添加了@WebService注解
* 对象绑定到一个地址的端口上。
*/
@WebService(serviceName = "DispatchService", // 与接口中指定的name一致
targetNamespace = "http://service.integrator.bw.com",// 与接口中的命名空间一致,一般是接口的包名倒序
endpointInterface = "com.bw.integrator.service.DispatchService"// 接口地址
)
@AutoPublish(publishAddr = "dispatch")
@Component
public class DispatchServiceImpl implements DispatchService{
/**
* 设备模型获取接口
* @param getDeviceInfo
* @return
*/
@Override
public static String getDeviceInfoRequest(String getDeviceInfo){
return "发布成功!";
}
}
二、客户端
1、cxf类库调用
a、下载安装并配置环境变量
Apache CXF 是开源的WebService框架,CXF帮助您使用前端编程api(如JAX-WS和JAX-RS)构建和开发服务。这些服务可以使用多种协议,如SOAP、XML/HTTP、RESTful HTTP或CORBA,并在多种传输协议(如HTTP、JMS或JBI)上工作。
注意事项:
apache-cxf-3.2.XX 开始JDK最低要求要JDK1.8而
apache-cxf-3.1.XX还是支持JDK1.7的
b、生成客户端代码
运行cmd;
进入D:\apache-cxf-3.2.7\bin界面;
运行wsdl生成客户端代码,例:
wsdl2java -d F:\inte\src\main\java -p service.integrator.bw.com -encoding utf-8 http://192.168.1.101:8080/ws/dispatch?wsdl
-p :指定存放包名
-d :指定存放本地目录
-encoding utf-8 :指定字符集
-client :生成客户端代码
-uri参数指定了wsdl文件的路径
import com.bw.dsm.ws.DispatchService;
import com.bw.dsm.ws.DispatchService_Service;
public static void main(String[] args) throws Exception {
//调用webservice
Map<String,String> info = new HashMap<>();
info.put("filename","TCL");
String infoString = JSON.toJSONString(info);
DispatchService hello= new DispatchService_Service().getDispatchServiceImplPort();
String deviceResult=hello.getDeviceInfoRequest(infoString);
System.out.println(deviceResult);
}
2、CXF的JaxWsDynamicClientFactory实现调用
public static void main(String[] args) throws Exception {
Map<String,String> info = new HashMap<>();
info.put("remoteUser","MyName");
info.put("filename","TCL");
String infoString = JSON.toJSONString(info);
// 创建动态客户端
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient("http://localhost:8081/webservice?wsdl");
Object[] objects = new Object[0];
try {
// invoke("方法名",参数1,参数2,参数3....);
objects = client.invoke("getDeviceInfoRequest", infoString);
System.out.println("返回数据:" + objects[0]);
} catch (java.lang.Exception e) {
e.printStackTrace();
}
}