根据wsdl生成webservice代码
环境准备
需要下载 apache-cxf-3.4.1
然后用bin目录下 wsdl2java.bat 来执行命令
命令
生成服务端代码命令
wsdl2java.bat -encoding utf-8 -d C:\Users\CHT\Downloads -impl D:\workspace\code\nhip-register\src\main\resources\wsdl\rhin_DocumentRetrievement.wsdl
生成客户端代码命令
wsdl2java.bat -encoding utf-8 -d C:\Users\CHT\Downloads\client -client D:\workspace\code\nhip-register\src\main\resources\wsdl\rhin_DocumentRetrievement.wsdl
常用命令:
-encoding :设置字符集
-p <pkg> : 指定代码的package名称
-d <data>: 指定生成的地址
-client : 服务说明
-o <path> : 指定生成代码的输出路径
-a : 生成异步模式的代码
-s : 生成同步模式的代码
-p <pkg> : 指定代码的package名称
-l <languange> : 使用的语言(Java/C) 默认是java
-t : 为代码生成测试用例
-ss : 生成服务端代码 默认不生成
-sd : 生成服务描述文件 services.xml,仅与-ss一同使用
-d <databinding> : 指定databingding,例如,adb,xmlbean,jibx,jaxme and jaxbri
-g : 生成服务端和客户端的代码
-pn <port_name> : 当WSDL中有多个port时,指定其中一个port
-sn <serv_name> : 选择WSDL中的一个service
-u : 展开data-binding的类
-r <path> : 为代码生成指定一个repository
-ssi : 为服务端实现代码生成接口类
-S : 为生成的源码指定存储路径
-R : 为生成的resources指定存储路径
--noBuildXML : 输出中不生成build.xml文件
--noWSDL : 在resources目录中不生成WSDL文件
--noMessageReceiver : 不生成MessageReceiver类
使用自定义注解发布webservice服务
概要
在springboot使用webservice,发布webservice服务的时候,我们经常需要手动在添加一些发布的代码,比如:
@Bean
public Endpoint organizationEndpoint() {
EndpointImpl endpoint = new EndpointImpl(bus, organizationProvider);
endpoint.publish("/organization");
//在服务端添加日志拦截器。
endpoint.getInInterceptors().add(new LoggingInInterceptor());
endpoint.getOutInterceptors().add(new LoggingOutInterceptor());
return endpoint;
}
每写一个服务就要发布一次,上面的代码就要重复一次,如是就想把这重复的代码通过注解的形式来简化,下面是具体实现。
代码
自定义注解
/**
* 自定义发布webservice服务注解
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface WsEndpoint {
@NotNull
@AliasFor("name")
String value() default "";
}
WebService接口服务发布配置
/**
* 负责发布WebService服务的配置
*
* 该方法通过WsEndpoint自定义注解来进行统一发布webservice服务
* 下方注释部分为正常写法的示例
*/
@Configuration
@Slf4j
public class CxfConfig implements CommandLineRunner, ApplicationContextAware, BeanDefinitionRegistryPostProcessor{
private ApplicationContext applicationContext;
private ConfigurableListableBeanFactory beanFactory;
/*@Autowired
private Bus bus;
@Resource
private OrganizationProvider organizationProvider;
*/
/**
* 发布 机构endpoint
*
* @return
*/
/* @Bean
public Endpoint organizationEndpoint() {
EndpointImpl endpoint = new EndpointImpl(bus, organizationProvider);
endpoint.publish("/organization");
//在服务端添加日志拦截器。后续还有更好的方法。
endpoint.getInInterceptors().add(new LoggingInInterceptor());
endpoint.getOutInterceptors().add(new LoggingOutInterceptor());
return endpoint;
}*/
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
// 拿到bean工厂对象
this.beanFactory = configurableListableBeanFactory;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
// 拿到上下文对象
this.applicationContext = applicationContext;
}
/**
* 项目启动完成后发布webservice服务,在项目没有启动完成前,
* 由于bean依赖之类的还没有注入,提前从上下文对象中拿到相关bean发布webservice服务可能会引发依赖问题。
* @param args
* @throws Exception
*/
@Override
public void run(String... args) throws Exception {
log.info("===============================.................. springboot启动完成,发布webservice服务 ...");
try {
Bus bus = applicationContext.getBean(Bus.class);
// 拿到标记了webservice注解的bean
String[] beanNamesForAnnotation = applicationContext.getBeanNamesForAnnotation(WebService.class);
if (null == beanNamesForAnnotation || beanNamesForAnnotation.length == 0) {
return;
}
// 需要发布的webservice服务
for (String beanName : beanNamesForAnnotation) {
Object bean = applicationContext.getBean(beanName);
// 解析自定义注解并拿到值
String path = analyzeClassAndInterfaceAnnotation(bean.getClass());
if (StringUtils.isBlank(path)) {
// 没有标记自定义注解的webservice服务不会发布
continue;
}
EndpointImpl endpoint = new EndpointImpl(bus, bean);
endpoint.publish(path);
//在服务端添加日志拦截器。后续还有更好的方法。
endpoint.getInInterceptors().add(new LoggingInInterceptor());
//返回200时,会记录下返回的SOAP报文。但未能返回200时,看上去记录的依然是输入时的SOAP报文
endpoint.getOutInterceptors().add(new LoggingOutInterceptor());
beanFactory.registerSingleton(path, endpoint);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 判断当前类及其实现的接口上是否有自定义注解,并且拿到自定义注解的值
*
* @param aClass
*/
private String analyzeClassAndInterfaceAnnotation(Class<?> aClass) {
// 判断当前类上是否有自定义注解
Annotation[] annotations = aClass.getAnnotations();
for (Annotation annotation : annotations) {
if (annotation instanceof WsEndpoint) {
return ((WsEndpoint) annotation).value();
}
}
// 判断实现的接口上是否有自定义注解
Class<?>[] interfaces = aClass.getInterfaces();
if (null == interfaces || interfaces.length == 0) {
return null;
}
for (Class<?> anInterface : interfaces) {
Annotation[] interfaceAnnotations = anInterface.getAnnotations();
if (null == interfaceAnnotations || interfaceAnnotations.length == 0) {
continue;
}
for (Annotation interfaceClassAnnotation : interfaceAnnotations) {
if (interfaceClassAnnotation instanceof WsEndpoint) {
return ((WsEndpoint) interfaceClassAnnotation).value();
}
}
}
return null;
}
}
使用
@WebService(targetNamespace = "http://www.chiss.org.cn/rhin/2015", name = "OrganizationProvider")
@XmlSeeAlso({ObjectFactory.class})
@WsEndpoint("organization") // 使用自定义注解发布webservice服务接口
public interface OrganizationProvider {
/**
* 机构注册
*
* @param message
* @return
* @throws SOAPException
*/
@WebMethod(operationName = "OrganizationFeed", action = "OrganizationFeed")
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
@WebResult(name = "OrganizationFeedResponse", targetNamespace = "http://www.chiss.org.cn/rhin/2015", partName = "message")
public OrganizationFeedResponse organizationFeed(
@WebParam(partName = "message", name = "OrganizationFeed", targetNamespace = "http://www.chiss.org.cn/rhin/2015")
OrganizationFeed message
) throws SOAPException;
/**
* 机构分页查询
*
* @param message
* @return
*/
@WebMethod(operationName = "OrganizationQuery", action = "OrganizationQuery")
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
@WebResult(name = "OrganizationQueryResponse", targetNamespace = "http://www.chiss.org.cn/rhin/2015", partName = "message")
public OrganizationQueryResponseMessage organizationQuery(
@WebParam(partName = "message", name = "OrganizationQuery", targetNamespace = "http://www.chiss.org.cn/rhin/2015")
OrganizationQueryRequest message
) throws SOAPException;
}
结果
springboot启动完成后进行webservice服务接口发布
发布后的接口