程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 詳解Spring boot+CXF開發WebService Demo

詳解Spring boot+CXF開發WebService Demo

編輯:關於JAVA

最近工作中需要用到webservice,而且結合spring boot進行開發,參照了一些網上的資料,配置過程中出現的了一些問題,於是寫了這篇博客,記錄一下我這次spring boot+cxf開發的webservice的配置過程,僅供參考。

一、本次開發除了用到spring boot基礎jar包外,還用到了cxf相關jar包:

<!-- cxf支持 -->
    <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>

二、首先我們創建一個實體類,內容是關於用戶信息的查詢和記錄:

import java.io.Serializable;
import java.util.Date;

public class User implements Serializable {

  private static final long serialVersionUID = -5939599230753662529L;
  private String       userId;
  private String      username;
  private String      age;
  private Date       updateTime;
  //getter setter ......
  public void setUserId(String userId) {
    this.userId=userId;
  }
  public void setUsername(String username) {
    this.username=username;
  }
  public void setAge(String age) {
    this.age=age;
  }
  public void setUpdateTime(Date updateTime) {
    this.updateTime=updateTime;
  }
  
  
  public String getUserId() {
    return userId;
  }
  public String getUserName() {
    return username;
  }
  public String getAge() {
    return age;
  }
  public Date getUpdateTime() {
    return updateTime;
  }
}

三、接下來我們創建接口類:

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

import cn.paybay.demo.entity.User;


@WebService
public interface UserService {

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

四、有了接口類,那麼接下來我們對接口進行實現,也就是接口實現類(也就是業務類)代碼:

package cn.paybay.demo.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;



import javax.jws.WebService;

import cn.paybay.demo.entity.User;
import cn.paybay.demo.service.UserService;

@WebService(targetNamespace="http://service.demo.paybay.cn/",endpointInterface = "cn.paybay.demo.service.UserService")
public class UserServiceImpl implements UserService{
  
  private Map<String, User> userMap = new HashMap<String, User>();
  public UserServiceImpl() {
    System.out.println("向實體類插入數據");
    User user = new User();
    user.setUserId("411001");
    user.setUsername("zhansan");
    user.setAge("20");
    user.setUpdateTime(new Date());
    userMap.put(user.getUserId(), user);
    
    user = new User();
    user.setUserId("411002");
    user.setUsername("lisi");
    user.setAge("30");
    user.setUpdateTime(new Date());
    userMap.put(user.getUserId(), user);
    
    user = new User();
    user.setUserId("411003");
    user.setUsername("wangwu");
    user.setAge("40");
    user.setUpdateTime(new Date());
    userMap.put(user.getUserId(), user);
  }
  @Override
  public String getName(String userId) {
    return "liyd-" + userId;
  }
  @Override
  public User getUser(String userId) {
    System.out.println("userMap是:"+userMap);
    return userMap.get(userId);
  }

}

注釋(PS):在發布服務之前,我們要在這裡對業務實現類進行一下說明,請大家看下圖箭頭指向的方框部分

下面我來解釋一下加上圖方框箭頭所指代碼的目的:

http://impl.service.demo.paybay.cn/:這是我的業務類所在路徑;

http://service.demo.paybay.cn/:這是我的接口類所在路徑;

在不加上圖方框箭頭所指代碼的情況下,你最後發服務的結果是這樣的(如下圖):

並且會在你進行客戶端調用的時候回報錯:No operation was found with the name {http://impl.service.demo.paybay.cn/}getUser.那麼原因就是:在CXF發布服務的時候,發布的是業務類(UserServiceImpl.java),那麼默認的命名空間就會是業務類所在包(路徑),而對外界暴露的則是接口類(UserService.java),那麼對於客戶端調用的時侯,需要按照接口類所在路徑進行命名空間的定義。

所以在發布之前我們要在業務類(UserServiceImpl.java)上增加注解,指定命名空間,然後再進行發布,

那麼我們最終在加上(圖一)方框箭頭所指代碼情況下,發布服務的結果為下圖(請看圖三):

五、(發布服務)接口類,業務類代碼都已經准備好,那麼我接下來我就要對webservice服務進行發布:

代碼如下:

import javax.xml.ws.Endpoint;

import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.transport.servlet.CXFServlet;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import cn.paybay.demo.service.UserService;
import cn.paybay.demo.service.impl.UserServiceImpl;


@Configuration
public class TestConfig {
  
     @Bean
    public ServletRegistrationBean dispatcherServlet() {
      return new ServletRegistrationBean(new CXFServlet(), "/test/*");
    }
    @Bean(name = Bus.DEFAULT_BUS_ID)
    public SpringBus springBus() {
      return new SpringBus();
    }
    @Bean
    public UserService userService() {
      return new UserServiceImpl();
    }
    @Bean
    public Endpoint endpoint() {
      EndpointImpl endpoint = new EndpointImpl(springBus(), userService());
      endpoint.publish("/user");
      return endpoint;
    }

}

那麼到這裡呢,我們的所有的步驟基本完成了,啟動spring boot 然後再浏覽器中輸入url:http://localhost:8080/webservice/test/user?wsdl

可以看到有相關的wsdl描述信息輸出了,說明服務已經發布了。

那麼這裡我又要增加注釋了,請大家注意,我在最初查詢資料,配置demo的時候,啟動以後,發布時候總是報404,網上有很多關於什麼端口沖突等說法,我試過後,根本不是那一回事,然後我無意中嘗試了一下,在url地址處加入工程名,結果,問題解決了。

因此請大家注意:在測試發布服務的時候,你在浏覽器中輸入的url地址應該是:http://localhost:8080/你的工程名/test/user?wsdl;

然後就是發布結果如下圖(見圖四):

到此為止,我們的服務發布成功了。

六、調用服務

import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;


public class Client {

  public static void main(String args[]) throws Exception{
    
    JaxWsDynamicClientFactory dcf =JaxWsDynamicClientFactory.newInstance();
    org.apache.cxf.endpoint.Client client =dcf.createClient("http://localhost:8080/webservice/test/user?wsdl");
    //getUser 為接口中定義的方法名稱 張三為傳遞的參數  返回一個Object數組
    Object[] objects=client.invoke("getUser","411001");
    //輸出調用結果
    System.out.println("*****"+objects[0].toString());
  }
  
}

七、最後附上我的工程結構圖(見圖五):

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved