Spring Boot 開發 WebService 服務


https://www.cnblogs.com/fishpro/p/spring-boot-study-webservice.html

驗證通過

 

WebService 雖然現在大部分互聯網企業不太提倡使用,但在以第三方接口為主導的市場,對方來什么接口你還得用什么接口,不可能把接口重寫了。例如大部分傳統的大型企業都在用 WebService,並且版本還不一樣。

本章主要介紹在 Spring Boot 下有常用的整合 WebService 的方法並給出示例。為了方便測試,本章有兩個獨立的項目

  1. 用戶的獲取、增加、更新、刪除 webservice 服務
  2. 用於調用 1 的webservice 服務的客戶端

本項目源碼 github 下載

1 新建 Spring Boot Maven 示例工程項目

注意:是用來 IDEA 開發工具

  1. File > New > Project,如下圖選擇 Spring Initializr 然后點擊 【Next】下一步
  2. 填寫 GroupId(包名)、Artifact(項目名) 即可。點擊 下一步
    groupId=com.fishpro
    artifactId=webservice
  3. 選擇依賴 Spring Web Starter 前面打鈎。
  4. 項目名設置為 spring-boot-study-webservice.

2 引入依賴 Pom.xml

這里主要是引入 org.apache.cxf

<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.cxf/cxf-spring-boot-starter-jaxws --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-spring-boot-starter-jaxws</artifactId> <version>3.2.5</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> 

3 編寫一個用戶獲取、新增、修改、刪除服務

3.1 傳輸對象 UserDto

通常我們把展示層與服務層之間傳輸的對象使用Dto后綴來標識。

UserDto(路徑 src/main/java/com/fishpro/webservice/dto/UserDto.java)


/** * 用戶傳輸實體對象 通常我們把展示層與服務層之間傳輸的對象使用Dto后綴來標識。 * */ public class UserDto { private Integer userId;//用戶id private String userName;//用戶名稱 private String password;//用戶密碼 private Integer sex;//用戶性別 0女 1男 public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Integer getSex() { return sex; } public void setSex(Integer sex) { this.sex = sex; } } 

3.2 用戶服務類

UserService 接口類(路徑 src/main/java/com/fishpro/webservice/service/UserService.java)

/** * 用戶服務類 必須使用 @WebService * */ @WebService(targetNamespace = WsConst.NAMESPACE_URI ,name = "userPortType") public interface UserService { /** * 根據用戶id獲取用戶信息 * */ @WebMethod(operationName="getUserById") UserDto get(@WebParam(name = "id") String id); /** * 獲取全部用戶信息 * */ @WebMethod(operationName="getUsers") List<UserDto> list(); /** * 獲取用戶數 * */ @WebMethod(operationName="count") int count(@); /** * 新增用戶 * */ @WebMethod(operationName="save") int save(@WebParam(name = "user") UserDto user); /** * 更新用戶 * */ @WebMethod(operationName="update") int update(@WebParam(name = "user") UserDto user); /** * 刪除用戶 * */ @WebMethod(operationName="remove") int remove(@WebParam(name = "id") Integer id); /** * 批量刪除用戶 * */ @WebMethod(operationName="batchRemove") int batchRemove(@WebParam(name = "ids") Integer[] ids); } 

UserServiceImpl 接口類(路徑 src/main/java/com/fishpro/webservice/service/UserServiceImpl.java)


@WebService( targetNamespace = WsConst.NAMESPACE_URI, //wsdl命名空間 name = "userPortType", //portType名稱 客戶端生成代碼時 為接口名稱 serviceName = "userService", //服務name名稱 portName = "userPortName", //port名稱 endpointInterface = "com.fishpro.webservice.service.UserService")//指定發布webservcie的接口類,此類也需要接入@WebService注解 public class UserServiceImpl implements UserService { @Override public UserDto get(String id){ if(null==id){ return null; } List<UserDto> list= getData(); UserDto UserDto=null; for (UserDto user:list ) { if(id.equals(user.getUserId().toString())){ UserDto=user; break; } } return UserDto; } @Override public List<UserDto> list(){ List<UserDto> list=new ArrayList<>(); list=getData(); return list; } @Override public int count(){ return getData().size(); } @Override public int save(UserDto user){ return 1; } @Override public int update(UserDto user){ return 1; } @Override public int remove(Integer id){ return 1; } @Override public int batchRemove(Integer[] ids){ return 1; } /** * 模擬一組數據 * */ private List<UserDto> getData(){ List<UserDto> list=new ArrayList<>(); UserDto UserDto=new UserDto(); UserDto.setUserId(1); UserDto.setUserName("admin"); list.add(UserDto); UserDto=new UserDto(); UserDto.setUserId(2); UserDto.setUserName("heike"); list.add(UserDto); UserDto=new UserDto(); UserDto.setUserId(3); UserDto.setUserName("tom"); list.add(UserDto); UserDto=new UserDto(); UserDto.setUserId(4); UserDto.setUserName("mac"); list.add(UserDto); return list; } } 

4 服務發布

編寫 CxfWebServiceConfig(路徑 src/main/java/com/fishpro/webservice/config/CxfWebServiceConfig.java)

import com.fishpro.websevice.service.UserService; import com.fishpro.websevice.service.impl.UserServiceImpl; 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 javax.xml.ws.Endpoint; @Configuration public class CxfWebServiceConfig { /** * * */ @Bean("cxfServletRegistration") public ServletRegistrationBean dispatcherServlet(){ return new ServletRegistrationBean(new CXFServlet(),"/ws/*"); } /** * 申明業務處理類 當然也可以直接 在實現類上標注 @Service */ @Bean public UserService userService() { return new UserServiceImpl(); } /* * 非必要項 */ @Bean(name = Bus.DEFAULT_BUS_ID) public SpringBus springBus() { SpringBus springBus = new SpringBus(); return springBus; } /* * 發布endpoint */ @Bean public Endpoint endpoint( ) { EndpointImpl endpoint = new EndpointImpl(springBus(), userService()); endpoint.publish("/user");//發布地址 return endpoint; } } 

打開瀏覽器輸入 http://localhost:8080/ws/user?wsdl 可以見到發布的效果

如何使用 Spring Boot 調用 WebService ,請閱讀 Spring Boot 使用 CXF 調用 WebService 服務

5 問題

  1. cxf 的服務方法中,是不能使用java.util.Map作為參數的,因為本身不支持轉換
    cxf對很多復雜類型支持並不友好,建議參數能使用簡單的類型,就使用簡單的類型

本項目源碼 github 下載

 

 

spring boot 下開發webservice接口

1、引入pom依賴

  1.  
    <!-- 引入CXF jar包 -->
  2.  
    <dependency>
  3.  
    <groupId>org.apache.cxf</groupId>
  4.  
    <artifactId>cxf-spring-boot-starter-jaxws</artifactId>
  5.  
    <version>3.3.3</version>
  6.  
    </dependency>

2、編寫webservice服務端

2.1 新建接口,並添加targetNamespace,targetNamespace是接口所在包的倒序,如果不添加,在動態調用接口的時候,會報錯誤信息。

  1.  
     
  2.  
    import javax.jws.WebParam;
  3.  
    import javax.jws.WebService;
  4.  
     
  5.  
    // ~ File Information
  6.  
    /**
  7.  
    * @author zxy
  8.  
    * @date 2019年9月23日 下午2:45:10
  9.  
    * 類說明:定義接口,targetNamespace是當前所在包的倒序。
  10.  
    */
  11.  
    @ WebService(targetNamespace="http://webservice.common.bmSystem.com")
  12.  
    public interface IHelloWord {
  13.  
     
  14.  
    // ~ Methods
  15.  
    public String say(@WebParam(name="helloName") String helloName);
  16.  
     
  17.  
    }

2.2 新建接口實現類,targetNamespace與實現接口保持一致,endpointInterface為接口所在包的全路徑。

  1.  
     
  2.  
    import javax.jws.WebService;
  3.  
     
  4.  
    import org.springframework.stereotype.Component;
  5.  
     
  6.  
    import com.bmSystem.common.webservice.IHelloWord;
  7.  
     
  8.  
    // ~ File Information
  9.  
    /**
  10.  
    * @author zxy
  11.  
    * @date 2019年9月23日 下午2:46:18
  12.  
    * 類說明:接口實現類,targetNamespace是當前所在包的倒序。
  13.  
    */
  14.  
    @Component
  15.  
    @WebService(targetNamespace="http://webservice.common.bmSystem.com",
  16.  
    endpointInterface ="com.bmSystem.common.webservice.IHelloWord")
  17.  
    public class HelloWordImpl implements IHelloWord{
  18.  
     
  19.  
    @Override
  20.  
    public String say(String str) {
  21.  
    System. out.println("進入接口...");
  22.  
    return str;
  23.  
    }
  24.  
     
  25.  
    }

3、發布webservice接口

  1.  
    package com.bmSystem.common.sys.config.webservice;
  2.  
     
  3.  
    import javax.xml.ws.Endpoint;
  4.  
    import org.apache.cxf.Bus;
  5.  
    import org.apache.cxf.bus.spring.SpringBus;
  6.  
    import org.apache.cxf.jaxws.EndpointImpl;
  7.  
    import org.apache.cxf.transport.servlet.CXFServlet;
  8.  
    import org.springframework.beans.factory.annotation.Autowired;
  9.  
    import org.springframework.boot.web.servlet.ServletRegistrationBean;
  10.  
    import org.springframework.context.annotation.Bean;
  11.  
    import org.springframework.context.annotation.Configuration;
  12.  
     
  13.  
    import com.bmSystem.common.webservice.impl.HelloWordImpl;
  14.  
     
  15.  
    // ~ File Information
  16.  
    /**
  17.  
    * @author zxy
  18.  
    * @date 2019年9月23日 下午3:12:00
  19.  
    * 類說明:webservice發布,默認訪問地址為:localhost:8080/services/helloWord?wsdl
  20.  
    *
  21.  
    */
  22.  
    @Configuration
  23.  
    public class WebServiceConfig {
  24.  
     
  25.  
    // ~ Fields
  26.  
    @Autowired
  27.  
    private HelloWordImpl helloWord;//接口實現類
  28.  
     
  29.  
    // ~ Methods
  30.  
     
  31.  
    /**
  32.  
    * 此方法作用是改變項目中服務名的前綴名,此處127.0.0.1或者localhost不能訪問時,請使用ipconfig查看本機ip來訪問
  33.  
    * 此方法被注釋后:wsdl訪問地址為http://127.0.0.1:8080/services/user?wsdl
  34.  
    * 去掉注釋后:wsdl訪問地址為:http://127.0.0.1:8080/soap/user?wsdl
  35.  
    * @return
  36.  
    */
  37.  
    /*
  38.  
    * @SuppressWarnings("all")
  39.  
    *
  40.  
    * @Bean public ServletRegistrationBean dispatcherServlet() { return new
  41.  
    * ServletRegistrationBean(new CXFServlet(), "/soap/*"); }
  42.  
    */
  43.  
     
  44.  
    @Bean(name = Bus.DEFAULT_BUS_ID)
  45.  
    public SpringBus springBus() {
  46.  
    return new SpringBus();
  47.  
    }
  48.  
     
  49.  
    @Bean
  50.  
    public Endpoint endpoint() {
  51.  
    EndpointImpl endpoint= new EndpointImpl(springBus(), helloWord);
  52.  
    endpoint.publish( "/helloWord");//訪問地址
  53.  
    return endpoint;
  54.  
    }
  55.  
     
  56.  
    }

4、開發webservice客戶端調用,這里采用的是動態調用方式(推薦)

  1.  
     
  2.  
    import java.util.HashMap;
  3.  
    import java.util.Map;
  4.  
     
  5.  
    import org.apache.cxf.endpoint.Client;
  6.  
    import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
  7.  
     
  8.  
    import com.google.gson.Gson;
  9.  
     
  10.  
    /**
  11.  
    * @author zxy
  12.  
    * @date 2020年6月5日 上午9:05:06
  13.  
    * @Description : 動態調用webservice接口
  14.  
    */
  15.  
    public class TestWebservice {
  16.  
     
  17.  
    public static void main(String[] args) {
  18.  
    // 創建動態客戶端
  19.  
    JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
  20.  
    Client client = dcf.createClient( "http://127.0.0.1:8085/services/helloWord?wsdl");
  21.  
    // 需要密碼的情況需要加上用戶名和密碼
  22.  
    // client.getOutInterceptors().add(new ClientLoginInterceptor(USER_NAME, PASS_WORD));
  23.  
    Object[] objects = new Object[0];
  24.  
    try {
  25.  
    // invoke("方法名",參數1,參數2,參數3....);
  26.  
    //json的形式
  27.  
    Map<String,Object> params=new HashMap<String,Object>();
  28.  
    params.put( "name", "dasda");
  29.  
    Gson gson = new Gson();
  30.  
    String json = gson.toJson(params);
  31.  
    objects = client.invoke( "say", json);
  32.  
    System.out.println( "返回數據:" + objects[0]);
  33.  
    } catch (java.lang.Exception e) {
  34.  
    e.printStackTrace();
  35.  
    }
  36.  
    }
  37.  
    }

axis方式調用webservice接口:

  1.  
    import javax.xml.namespace.QName;
  2.  
    import javax.xml.rpc.ParameterMode;
  3.  
     
  4.  
    import org.apache.axis.client.Call;
  5.  
    import org.apache.axis.client.Service;
  6.  
    import org.apache.axis.encoding.XMLType;
  7.  
     
  8.  
    public class Test01 {
  9.  
    public static void main(String[] args) {
  10.  
    try {
  11.  
    //1、直接引用遠程的wsdl文件
  12.  
    String endpoint = "接口訪問路徑";
  13.  
    Service service = new Service();
  14.  
    Call call = (Call) service.createCall(); //創建服務
  15.  
    call.setTargetEndpointAddress(endpoint);
  16.  
    //2、定義報名和接口方法
  17.  
    call.setOperationName( new QName("targetNamespace", //wsdl文件中的targetNamespace
  18.  
    "getAllResourceDetail") //接口實現功能的方法
  19.  
    );
  20.  
     
  21.  
    //3、設置參數
  22.  
    call.addParameter( "resType", XMLType.XSD_INT,ParameterMode.IN);// 接口的參數
  23.  
    call.addParameter( "nodeIndexCode",XMLType.XSD_STRING,ParameterMode.IN);// 接口的參數
  24.  
    call.setReturnType(XMLType.XSD_STRING); // 設置返回類型
  25.  
     
  26.  
    int resType= 1000;
  27.  
    String nodeIndexCode="";
  28.  
     
  29.  
    //4、給方法傳遞參數,並且調用方法
  30.  
    String result = (String) call.invoke(new Object[] {nodeIndexCode ,resType});
  31.  
    System.out.println(result);
  32.  
    } catch (Exception e) {
  33.  
    e.printStackTrace();
  34.  
    }
  35.  
    }
  36.  
    }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM