Spring boot 整合CXF開(kāi)發(fā)web service示例
前言
說(shuō)起web service最近幾年restful大行其道,大有取代傳統(tǒng)soap web service的趨勢(shì),但是一些特有或相對(duì)老舊的系統(tǒng)依然使用了傳統(tǒng)的soap web service,例如銀行、航空公司的機(jī)票查詢接口等。
目前就遇到了這種情況,需要在系統(tǒng)中查詢第三方提供的soap web service接口,也就是說(shuō)要將它整合進(jìn)現(xiàn)有的系統(tǒng)當(dāng)中。
spring整合CXF本來(lái)十分簡(jiǎn)單,但是因?yàn)槭褂昧薙pring boot,不想用以前xml一堆配置的方式,那么能否按照Spring boot的風(fēng)格優(yōu)雅的進(jìn)行整合呢?
答案當(dāng)然是肯定的,但是遍查網(wǎng)上幾乎沒(méi)有這方面的資料,折騰過(guò)后覺(jué)得還是有必要記錄一下,雖然它顯得非常的簡(jiǎn)單。
添加依賴
Maven的項(xiàng)目,首先當(dāng)然是添加依賴了,除了原先Spring boot的依賴之外,還需要添加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>
編寫業(yè)務(wù)代碼
這里我們以查詢用戶信息為例,創(chuàng)建一個(gè)自定義的User對(duì)象:
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 ......
}
接下來(lái)創(chuàng)建一個(gè)用于提供web service服務(wù)的用戶接口,共兩個(gè)方法getName和getUser,一個(gè)返回普通的String,一個(gè)返回自定義對(duì)象:
@WebService
public interface UserService {
@WebMethod
String getName(@WebParam(name = "userId") Long userId);
@WebMethod
User getUser(Long userId);
}
有接口當(dāng)然要有業(yè)務(wù)代碼實(shí)現(xiàn)了,這里我們只做簡(jiǎn)單的演示:
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.setEmail("liyd1@qq.com");
user.setGmtCreate(new Date());
userMap.put(user.getUserId(), user);
user = new User();
user.setUserId(10002L);
user.setUsername("liyd2");
user.setEmail("liyd2@qq.com");
user.setGmtCreate(new Date());
userMap.put(user.getUserId(), user);
user = new User();
user.setUserId(10003L);
user.setUsername("liyd3");
user.setEmail("liyd3@qq.com");
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ā)布服務(wù)
接口和業(yè)務(wù)代碼我們都寫完了,剩下的就是發(fā)布服務(wù)了,也就是Spring boot和cxf的整合。
其實(shí)這二者的整合十分的簡(jiǎn)單,比以前xml的方式更加的簡(jiǎn)潔,所有相關(guān)的代碼如下:
@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ā)布服務(wù),都只需要一二行代碼,出乎意料的簡(jiǎn)單吧?
到這里我們所有的操作就都完成了,啟動(dòng)Spring boot,訪問(wèn) http://localhost:8080/soap/user?wsdl
可以看到有相關(guān)的wsdl描述信息輸出了,說(shuō)明服務(wù)已經(jīng)發(fā)布了。
調(diào)用服務(wù)
發(fā)布了web service服務(wù),那怎么調(diào)用呢,像整合一些第三方接口也是先有調(diào)用才后有發(fā)布???
調(diào)用soap web service,一般的方法是根據(jù)wsdl生成客戶端代碼,整合之后就可以像調(diào)用本地接口一樣使用了。
但是我個(gè)人不怎么喜歡這種方式,每個(gè)接口都要生成一次還有一堆的代碼,感覺(jué)比較麻煩。
相對(duì)更喜歡傳入方法名調(diào)用的方式,顯得清爽而簡(jiǎn)潔,以下就是所有代碼了:
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)用的服務(wù)接口返回的是一個(gè)自定義對(duì)象,那么結(jié)果Object[]中的數(shù)據(jù)類型就成了這個(gè)自定義對(duì)象(組件幫你自動(dòng)生成了這個(gè)對(duì)象),
但是你本地可能并沒(méi)有這個(gè)類,所以需要自行轉(zhuǎn)換處理,最簡(jiǎn)單的是新建一個(gè)跟返回結(jié)果一模一樣的類進(jìn)行強(qiáng)轉(zhuǎn),當(dāng)然更好的方式是封裝一個(gè)通用的,這個(gè)不是本文主題就不在這深入討論了。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
解決Mybatis報(bào)錯(cuò):org.apache.ibatis.reflection.ReflectionException
文章主要討論了在使用MyBatis進(jìn)行數(shù)據(jù)庫(kù)操作時(shí)遇到的幾個(gè)常見(jiàn)問(wèn)題及其解決方法,首先,文章指出如果DTO類中沒(méi)有定義getter和setter方法,會(huì)導(dǎo)致反射異常,解決方法是使用Lombok的@Data注解自動(dòng)生成這些方法2025-01-01
詳解Java如何使用責(zé)任鏈默認(rèn)優(yōu)雅地進(jìn)行參數(shù)校驗(yàn)
項(xiàng)目中參數(shù)校驗(yàn)十分重要,它可以保護(hù)我們應(yīng)用程序的安全性和合法性。這篇文章主要介紹了如何使用責(zé)任鏈默認(rèn)優(yōu)雅地進(jìn)行參數(shù)校驗(yàn),需要的可以參考一下2023-03-03
java基礎(chǔ)(System.err和System.out)詳解
下面小編就為大家?guī)?lái)一篇java基礎(chǔ)(System.err和System.out)詳解。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-06-06
GC調(diào)優(yōu)實(shí)戰(zhàn)之高分配速率High?Allocation?Rate
這篇文章主要為大家介紹了GC調(diào)優(yōu)之高分配速率High?Allocation?Rate的實(shí)戰(zhàn)示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-01-01
springboot項(xiàng)目中統(tǒng)一時(shí)間格式處理方法
JacksonConfiguration主要用于配置JSON的序列化和反序列化,而LocalDateTimeFormatter則用于處理請(qǐng)求和響應(yīng)中的LocalDateTime格式,這兩個(gè)配置項(xiàng)在SpringBoot項(xiàng)目中至關(guān)重要,確保數(shù)據(jù)格式的正確處理和傳輸2024-10-10
SpringCloud將Nacos作為配置中心實(shí)現(xiàn)流程詳解
這篇文章主要介紹了Springcloud中的Nacos Config服務(wù)配置,本文以用戶微服務(wù)為例,進(jìn)行統(tǒng)一的配置,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-10-10
java對(duì)象list使用stream根據(jù)某一個(gè)屬性轉(zhuǎn)換成map的3種方式舉例
開(kāi)發(fā)小伙伴們通常會(huì)需要使用到對(duì)象和Map互相轉(zhuǎn)換的開(kāi)發(fā)場(chǎng)景,下面這篇文章主要給大家介紹了關(guān)于java對(duì)象list使用stream根據(jù)某一個(gè)屬性轉(zhuǎn)換成map的3種方式,需要的朋友可以參考下2024-01-01

