首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Spring Boot 整合 Apache CXF 發布 WebService 完整指南

     編輯:Java 相關知識

專案背景與依賴準備

因業務需求需對外提供 SOAP WebService,技術棧為 Spring Boot 2.x + Apache CXF 3.1.6。Maven 核心依賴:

<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-frontend-jaxws</artifactId>
    <version>3.1.6</version>
</dependency>
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-transports-http</artifactId>
    <version>3.1.6</version>
</dependency>

領域模型與服務合約定義

實體類:User

public class User implements Serializable {
    private String userId;
    private String username;
    private String age;
    private Date updateTime;
    // Getter/Setter 省略
}

服務介面:UserService(SEI - Service Endpoint Interface)

@WebService
public interface UserService {
    @WebMethod
    String getName(@WebParam(name = "userId") String userId);

    @WebMethod
    User getUser(@WebParam(name = "userId") String userId);
}

服務實現:UserServiceImpl

@WebService(
    targetNamespace = "https://service.demo.paybay.cn/",
    endpointInterface = "cn.paybay.demo.service.UserService"
)
public class UserServiceImpl implements UserService {
    private Map<String, User> userMap = new HashMap<>();

    public UserServiceImpl() {
        // 初始化測試數據
        User u1 = new User(); u1.setUserId("411001"); u1.setUsername("zhansan"); u1.setAge("20"); u1.setUpdateTime(new Date());
        User u2 = new User(); u2.setUserId("411002"); u2.setUsername("lisi"); u2.setAge("30"); u2.setUpdateTime(new Date());
        User u3 = new User(); u3.setUserId("411003"); u3.setUsername("wangwu"); u3.setAge("40"); u3.setUpdateTime(new Date());
        userMap.put(u1.getUserId(), u1);
        userMap.put(u2.getUserId(), u2);
        userMap.put(u3.getUserId(), u3);
    }

    @Override public String getName(String userId) { return "liyd-" + userId; }
    @Override public User getUser(String userId) { return userMap.get(userId); }
}

關鍵配置:命名空間一致性問題

核心坑點:CXF 發布的是實現類,預設命名空間為實現類包路徑(https://impl.service.demo.paybay.cn/),但 WSDL 對外暴露的是介面類,客戶端按介面類命名空間(https://service.demo.paybay.cn/)調用,導致命名空間不匹配報錯:

No operation was found with the name {https://impl.service.demo.paybay.cn/}getUser

解決方案

在實現類上显式指定 targetNamespace 與介面一致:

@WebService(
    targetNamespace = "https://service.demo.paybay.cn/",  // 必須與介面命名空間一致
    endpointInterface = "cn.paybay.demo.service.UserService"
)

發布後 WSDL 的 targetNamespace 即為介面命名空間,客戶端調用正常。

Spring Boot 整合配置類

@Configuration
public class CxfConfig {

    // 註冊 CXF Servlet,映射路徑 /test/*
    @Bean
    public ServletRegistrationBean<CXFServlet> dispatcherServlet() {
        return new ServletRegistrationBean<>(new CXFServlet(), "/test/*");
    }

    // 提供 SpringBus
    @Bean(name = Bus.DEFAULT_BUS_ID)
    public SpringBus springBus() {
        return new SpringBus();
    }

    // 註冊服務實現 Bean
    @Bean
    public UserService userService() {
        return new UserServiceImpl();
    }

    // 發布端點
    @Bean
    public Endpoint endpoint(SpringBus springBus, UserService userService) {
        EndpointImpl endpoint = new EndpointImpl(springBus, userService);
        endpoint.publish("/user");  // 相對路徑
        return endpoint;
    }
}

驗證發布與常見 404 問題

正確訪問 WSDL 地址

https://localhost:8080/{context-path}/test/user?wsdl

注意:必須包含專案上下文路徑(context-path),否則會 404。若 server.servlet.context-path=/webservice,則完整路徑為:

https://localhost:8080/webservice/test/user?wsdl

成功發布標誌

瀏覽器顯示 WSDL XML 文檔,包含 <wsdl:definitions>、<wsdl:service> 等標準結構。

客戶端調用示例

public class Client {
    public static void main(String[] args) throws Exception {
        JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
        org.apache.cxf.endpoint.Client client = dcf.createClient(
            "https://localhost:8080/webservice/test/user?wsdl"
        );
        // 呼叫 getUser 方法
        Object[] result = client.invoke("getUser", "411001");
        System.out.println("調用結果:" + result[0]);
    }
}

專案結構參考

src/main/java
├── cn.paybay.demo
│   ├── entity.User
│   ├── service.UserService
│   ├── service.impl.UserServiceImpl
│   └── config.CxfConfig
└── Application.java

進階提示

  • 複雜類型傳遞:實體類需實現 Serializable,建議加上 @XmlAccessorType(XmlAccessType.FIELD) 控制序列化
  • 異常處理:定義 @WebFault 自定義 SOAP Fault
  • 安全性:整合 WS-Security 實現簽名/加密
  • 效能優化:啟用 MTOM 處理大型二進制附件

總結

Spring Boot + CXF 發布 WebService 核心步驟:

  1. 引入 cxf-rt-frontend-jaxws、cxf-rt-transports-http
  2. 定義 SEI(@WebService 介面)與實現類
  3. 關鍵:實現類指定 targetNamespace 與介面一致
  4. 配置 CXFServlet、SpringBus、EndpointImpl.publish()
  5. 驗證 WSDL 含 context-path

避開命名空間不一致這一最大坑點,即可快速構建穩定的 SOAP 服務。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved