webservice笔记

根据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服务接口发布
在这里插入图片描述
发布后的接口
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值