通过springboot发布WebService接口并调用方式

 更新时间:2025年09月24日 17:20:32   作者:大乐哥。  
Spring Boot集成CXF需注意版本对应,配置注解并发布服务,通过WSDL验证,结合Controller和Swagger测试,CXF支持SOAP、REST等服务,提供代码与合同优先开发模式

SpringBoot集成cxf步骤记录

1.什么是cxf

Apache CXF是一个开源的Service框架,简化用户的service开发,基于CXF开发的应用可提供SOAP、XML/HTTP、RESTFUL HTTP或CORBA等服务。CXF底层页可以使用不同的传输协议,包括HTTP、JMS或JBI等。

cxf特性

支持大量的Web Service标准:包括SOAP、WS-I Basic Profile、WSDL、WS-Addressing、WS-Policy、WS-ReliableMessaging和WS-Security。

支持大量的前端(frontend)编程模型。CXF实现了标准的JAX-WS API,它也包括一种被称为简单前端(simple frontend)的模型,这种模型无需annotation支持。

CXF支持web service的两种开发模式:

  • 规则(contract)优先: 通过编写WSDL来开发web service;
  • 代码优先: 通过编写java代码来开发webservice.

2.集成引入

    <!-- cxf start -->
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-spring-boot-starter-jaxws</artifactId>
            <version>3.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-features-logging</artifactId>
            <version>3.3.0</version>
        </dependency>
        <!-- cxf end -->

注意事项:cxf版本需要与SpringBoot的版本对应,不然因版本问题, 整合cxf-spring-boot-starter-jaxws的启动项目会出现异常。

具体对应关系上仓库进行查看下

https://mvnrepository.com/artifact/org.apache.cxf/cxf-spring-boot-starter-jaxws查找到jaxws的各种版本,进入之后可以看到对应的springboot版本

3.服务端

3.1 CXF配置类

package com.mrxu.config;

import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.ext.logging.LoggingFeature;
import org.springframework.context.annotation.Bean;

/**
 * <b>功能描述:CXF配置类</b><br>
 *
 * @author newzhong
 * @version 1.0.0
 * @since JDK 1.8
 */
public class CxfConfig {
    @Bean(name = Bus.DEFAULT_BUS_ID)
    public SpringBus springBus() {
        SpringBus bus = new SpringBus();
        bus.getFeatures().add(new LoggingFeature());
        return bus;
    }
}

3.2 服务的发布

自定义注解标注要发布的服务类,发布出去

package com.mrxu.config;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * <p>description:自动发布接口地址注解</p>
 *
 * @author newzhong
 * @version 1.0
 */
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoPublish {
    /**
     *<p>description:发布地址</p>
     * @return String
     * @author newzhong
     */
    String publishAddress();
}


package com.mrxu.config;

import lombok.extern.slf4j.Slf4j;
import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.jaxws.EndpointImpl;
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;

@Component
@Slf4j
public class PublishEndpoint implements ApplicationRunner {

    @Autowired
    private WebApplicationContext applicationConnect;

    @Autowired()
    @Qualifier(Bus.DEFAULT_BUS_ID)
    private SpringBus bus;

    @SuppressWarnings("resource")
    @Override
    public void run(ApplicationArguments applicationArguments) throws Exception {
        log.info("开始进行自动发布webService接口");

        String[] beanNames = applicationConnect.getBeanNamesForAnnotation(AutoPublish.class);
        for(String beanName : beanNames) {
            String publishAddr = applicationConnect.getType(beanName).getAnnotation(AutoPublish.class).publishAddress();
            EndpointImpl endpoint = new EndpointImpl(bus, applicationConnect.getBean(beanName));
            endpoint.publish(publishAddr);

            log.info(String.format("发布接口地址:[%s]", publishAddr));
        }

        log.info("weBservice接口自动发布结束");
    }

}


3.3 发布的地址yml,nacos配置

cxf:

path: /cxf

原本默认的默认端口号后 +拼接 /service,现在可以根据需求进行修改

3.4. 新增服务接口

在接口上添加@WebService注解

  • @WebParam表示方法的参数,如果不加此注解,方法的参数都从arg0,开始,随着参数增多,name不断增加为arg1,arg2…;
  • @WebResult表示方法的返回值, 没有此注解 返回值名字为return
package com.mrxu.service;

import javax.jws.WebParam;
import javax.jws.WebService;

/**
 * <b>功能描述:webService测试接口</b><br>
 * @author newzhong
 * @version 1.0.0
 * @since JDK 1.8
 *
 * @Note
 * <b>创建时间:</b> 2021-03-27 14:32
 */
@WebService(targetNamespace = "http://service.mrxu.com/")
public interface IWebServiceTest {

    String getDept(@WebParam(name = "jsonStr")String jsonStr);
}

3.5 新增服务接口实现类

  • serviceName: 对外发布的服务名,指定 Web Service 的服务名称:wsdl:service。缺省值为 Java 类的简单名称 + Service。(字符串)
  • endpointInterface: 服务接口全路径, 指定做SEI(Service EndPoint Interface)服务端点接口
  • name:此属性的值包含XML Web Service的名称。在默认情况下,该值是实现XML Web Service的类的名称,wsdl:portType 的名称。缺省值为 Java 类或接口的非限定名称。(字符串
  • portName: wsdl:portName。缺省值为 WebService.name+Port。
  • targetNamespace:指定你想要的名称空间,认是使用接口实现类的包名的反缀
  • wsdlLocation:指定用于定义 Web Service 的 WSDL 文档的 Web 地址。Web 地址可以是相对路径或绝对路径。(字符串)

注意:实现类上可以不添加Webservice注解 ,加在接口上

package com.mrxu.service.impl;

import com.mrxu.common.domain.Phone;
import com.mrxu.config.AutoPublish;
import com.mrxu.dao.PhoneMapper;
import com.mrxu.service.IWebServiceTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.jws.WebService;
import java.util.List;


@Service("WebServiceTest")
@AutoPublish(publishAddress = "test")
@WebService(endpointInterface = "com.mrxu.service.IWebServiceTest",
            serviceName = "WebServiceTest",
            targetNamespace = "http://service.mrxu.com/"
)
public class WebServiceTest implements IWebServiceTest {

    @Autowired
    public PhoneMapper phoneMapper;

    @Override
    public String getDept(String jsonStr) {
        List<Phone> phones = phoneMapper.selectPhone();
        String s = phones.toString();
        return s;
    }
}

3.6 验证服务发布

通过浏览器访问wsdl,wsdl路径即为发布的路径加上?wsdl

http://127.0.0.1:[端口号]/cxf/test?wsdl


可以看到接口就成功了。

测试webservice接口

1.新建一个controller

package com.mrxu.controller;

import com.mrxu.service.TestWebService;
import io.swagger.annotations.Api;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@Api(tags = "webser")
@RestController
@RequestMapping("/wbser")
public class WebServiceController {

    private static final long CONNECT_TIMEOUT = 10 * 1000;

    private static final long RECEIVE_TIMEOUT = 60 * 1000;

    private static final String ACTINFO_WSDL = "http://175.2.70.225:9002/cxf/test?wsdl";

    private TestWebService service = getProxyService(ACTINFO_WSDL, TestWebService.class);

    @PostMapping("/wbser")
    public String wbeser(String id){
        String userService = service.getDept("1");
        return userService;
    }


    public static <T> T getProxyService(String wsdl, Class<T> serviceClass) {
        JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
        factory.setServiceClass(serviceClass);
        factory.setAddress(wsdl);
        T service = (T) factory.create();
        org.apache.cxf.endpoint.Client proxy = ClientProxy.getClient(service);
        HTTPConduit conduit = (HTTPConduit) proxy.getConduit();
        HTTPClientPolicy policy = new HTTPClientPolicy();
        policy.setConnectionTimeout(CONNECT_TIMEOUT);
        policy.setReceiveTimeout(RECEIVE_TIMEOUT);
        conduit.setClient(policy);
        return service;
    }
}

2.新建一个WebService接口

package com.mrxu.service;


import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;


@WebService(targetNamespace="http://service.mrxu.com/")
public interface TestWebService {

    @WebMethod
    @WebResult
    String getData(@WebParam String requestData);

    @WebMethod
    @WebResult
    String getData1(@WebParam String requestData);

    @WebMethod
    @WebResult
    String getDept(@WebParam(name = "jsonStr")String id);
}

最后可以通过swagger进行测试

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 简单的用java实现读/写文本文件的示例

    简单的用java实现读/写文本文件的示例

    同时也展示了如果从输入流中读出来内容写入输出流中(仅限文本流) 三个例子可以独立存在,所以根据需要只看其中一个就行了。
    2008-07-07
  • 深入探究Java编程是值传递还是引用传递

    深入探究Java编程是值传递还是引用传递

    大家好,本篇文章主要讲的是Java编程是值传递还是引用传递的探究,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-04-04
  • 【Java】BigDecimal实现加减乘除运算代码

    【Java】BigDecimal实现加减乘除运算代码

    本篇文章主要介绍了【Java】BigDecimal实现加减乘除运算代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02
  • java图形化界面实现登录窗口

    java图形化界面实现登录窗口

    这篇文章主要为大家详细介绍了java图形化界面实现登录窗口,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-05-05
  • Java AOP实现自定义滑动窗口限流器方法详解

    Java AOP实现自定义滑动窗口限流器方法详解

    这篇文章主要介绍了Java AOP实现自定义滑动窗口限流器方法,其中滑动窗口算法弥补了计数器算法的不足,滑动窗口算法把间隔时间划分成更小的粒度,当更小粒度的时间间隔过去后,把过去的间隔请求数减掉,再补充一个空的时间间隔,需要的朋友可以参考下
    2022-07-07
  • SSM框架中测试单元的使用 spring整合Junit过程详解

    SSM框架中测试单元的使用 spring整合Junit过程详解

    这篇文章主要介绍了SSM框架中测试单元的使用 spring整合Junit过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • Java Swing的层次结构深入理解

    Java Swing的层次结构深入理解

    这篇文章主要介绍了Java Swing的层次结构深入理解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • Java 8 Stream操作类型及peek示例解析

    Java 8 Stream操作类型及peek示例解析

    这篇文章主要介绍了Java 8 Stream操作类型及peek示例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • Spring Boot中如何使用断路器详解

    Spring Boot中如何使用断路器详解

    这篇文章主要给大家介绍了关于Spring Boot中如何使用断路器的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-08-08
  • Java基础题新手练习(二)

    Java基础题新手练习(二)

    下面小编就为大家带来一篇Java基础的几道练习题(分享)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望可以帮到你
    2021-07-07

最新评论