前言
說起web service最近幾年restful大行其道,大有取代傳統(tǒng)soap web service的趨勢,但是一些特有或相對老舊的系統(tǒng)依然使用了傳統(tǒng)的soap web service,例如銀行、航空公司的機票查詢接口等。
目前就遇到了這種情況,需要在系統(tǒng)中查詢第三方提供的soap web service接口,也就是說要將它整合進現(xiàn)有的系統(tǒng)當中。
spring整合CXF本來十分簡單,但是因為使用了Spring boot,不想用以前xml一堆配置的方式,那么能否按照Spring boot的風格優(yōu)雅的進行整合呢?
答案當然是肯定的,但是遍查網(wǎng)上幾乎沒有這方面的資料,折騰過后覺得還是有必要記錄一下,雖然它顯得非常的簡單。
添加依賴
Maven的項目,首先當然是添加依賴了,除了原先Spring boot的依賴之外,還需要添加cxf依賴:
1
2
3
4
5
6
7
8
9
10
|
< 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 > |
編寫業(yè)務代碼
這里我們以查詢用戶信息為例,創(chuàng)建一個自定義的User對象:
1
2
3
4
5
6
7
8
|
public class User implements Serializable { private static final long serialVersionUID = -5939599230753662529L; private Long userId; private String username; private String email; private Date gmtCreate; //getter setter ...... } |
接下來創(chuàng)建一個用于提供web service服務的用戶接口,共兩個方法getName
和getUser
,一個返回普通的String,一個返回自定義對象:
1
2
3
4
5
6
7
|
@WebService public interface UserService { @WebMethod String getName( @WebParam (name = "userId" ) Long userId); @WebMethod User getUser(Long userId); } |
有接口當然要有業(yè)務代碼實現(xiàn)了,這里我們只做簡單的演示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
public class UserServiceImpl implements UserService { private Map<Long, User> userMap = new HashMap<Long, User>(); public UserServiceImpl() { User user = new User(); user.setUserId(10001L); user.setUsername( "liyd1" ); user.setGmtCreate( new Date()); userMap.put(user.getUserId(), user); user = new User(); user.setUserId(10002L); user.setUsername( "liyd2" ); user.setGmtCreate( new Date()); userMap.put(user.getUserId(), user); user = new User(); user.setUserId(10003L); user.setUsername( "liyd3" ); user.setGmtCreate( new Date()); userMap.put(user.getUserId(), user); } @Override public String getName(Long userId) { return "liyd-" + userId; } @Override public User getUser(Long userId) { return userMap.get(userId); } } |
發(fā)布服務
接口和業(yè)務代碼我們都寫完了,剩下的就是發(fā)布服務了,也就是Spring boot和cxf的整合。
其實這二者的整合十分的簡單,比以前xml的方式更加的簡潔,所有相關的代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
@Configuration public class CxfConfig { @Bean public ServletRegistrationBean dispatcherServlet() { return new ServletRegistrationBean( new CXFServlet(), "/soap/*" ); } @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; } } |
可以看到從配置cxf到發(fā)布服務,都只需要一二行代碼,出乎意料的簡單吧?
到這里我們所有的操作就都完成了,啟動Spring boot,訪問 http://localhost:8080/soap/user?wsdl
可以看到有相關的wsdl描述信息輸出了,說明服務已經(jīng)發(fā)布了。
調(diào)用服務
發(fā)布了web service服務,那怎么調(diào)用呢,像整合一些第三方接口也是先有調(diào)用才后有發(fā)布啊?
調(diào)用soap web service,一般的方法是根據(jù)wsdl生成客戶端代碼,整合之后就可以像調(diào)用本地接口一樣使用了。
但是我個人不怎么喜歡這種方式,每個接口都要生成一次還有一堆的代碼,感覺比較麻煩。
相對更喜歡傳入方法名調(diào)用的方式,顯得清爽而簡潔,以下就是所有代碼了:
1
2
3
4
5
6
|
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance(); Client client = dcf.createClient( "http://localhost:8080/soap/user?wsdl" ); Object[] objects = client.invoke( "getUser" , 10002L); //輸出調(diào)用結(jié)果 System.out.println(objects[ 0 ].getClass()); System.out.println(objects[ 0 ].toString()); |
這種方式要注意的就是,如果調(diào)用的服務接口返回的是一個自定義對象,那么結(jié)果Object[]中的數(shù)據(jù)類型就成了這個自定義對象(組件幫你自動生成了這個對象),
但是你本地可能并沒有這個類,所以需要自行轉(zhuǎn)換處理,最簡單的是新建一個跟返回結(jié)果一模一樣的類進行強轉(zhuǎn),當然更好的方式是封裝一個通用的,這個不是本文主題就不在這深入討論了。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://blog.csdn.net/hj7jay/article/details/51130386