使用自定义注解发布webservice服务
- 概要
- 代码
- 自定义注解
- 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;/*@Autowiredprivate Bus bus;@Resourceprivate OrganizationProvider organizationProvider;*//*** 发布 机构endpoint** @return*//* @Beanpublic Endpoint organizationEndpoint() {EndpointImpl endpoint = new EndpointImpl(bus, organizationProvider);endpoint.publish("/organization");//在服务端添加日志拦截器。后续还有更好的方法。endpoint.getInInterceptors().add(new LoggingInInterceptor());endpoint.getOutInterceptors().add(new LoggingOutInterceptor());return endpoint;}*/@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {}@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {// 拿到bean工厂对象this.beanFactory = configurableListableBeanFactory;}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {// 拿到上下文对象this.applicationContext = applicationContext;}/*** 项目启动完成后发布webservice服务,在项目没有启动完成前,* 由于bean依赖之类的还没有注入,提前从上下文对象中拿到相关bean发布webservice服务可能会引发依赖问题。* @param args* @throws Exception*/@Overridepublic void run(String... args) throws Exception {log.info("===============================.................. springboot启动完成,发布webservice服务 ...");try {Bus bus = applicationContext.getBean(Bus.class);// 拿到标记了webservice注解的beanString[] 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服务接口发布
发布后的接口