詳解Spring boot+CXF開發(fā)WebService Demo
最近工作中需要用到webservice,而且結(jié)合spring boot進(jìn)行開發(fā),參照了一些網(wǎng)上的資料,配置過程中出現(xiàn)的了一些問題,于是寫了這篇博客,記錄一下我這次spring boot+cxf開發(fā)的webservice的配置過程,僅供參考。
一、本次開發(fā)除了用到spring boot基礎(chǔ)jar包外,還用到了cxf相關(guān)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>
二、首先我們創(chuàng)建一個(gè)實(shí)體類,內(nèi)容是關(guān)于用戶信息的查詢和記錄:
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;
}
}
三、接下來我們創(chuàng)建接口類:
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);
}
四、有了接口類,那么接下來我們對(duì)接口進(jìn)行實(shí)現(xiàn),也就是接口實(shí)現(xiàn)類(也就是業(yè)務(wù)類)代碼:
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("向?qū)嶓w類插入數(shù)據(jù)");
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):在發(fā)布服務(wù)之前,我們要在這里對(duì)業(yè)務(wù)實(shí)現(xiàn)類進(jìn)行一下說明,請(qǐng)大家看下圖箭頭指向的方框部分

下面我來解釋一下加上圖方框箭頭所指代碼的目的:
http://impl.service.demo.paybay.cn/:這是我的業(yè)務(wù)類所在路徑;
http://service.demo.paybay.cn/:這是我的接口類所在路徑;
在不加上圖方框箭頭所指代碼的情況下,你最后發(fā)服務(wù)的結(jié)果是這樣的(如下圖):

并且會(huì)在你進(jìn)行客戶端調(diào)用的時(shí)候回報(bào)錯(cuò):No operation was found with the name {http://impl.service.demo.paybay.cn/}getUser.那么原因就是:在CXF發(fā)布服務(wù)的時(shí)候,發(fā)布的是業(yè)務(wù)類(UserServiceImpl.java),那么默認(rèn)的命名空間就會(huì)是業(yè)務(wù)類所在包(路徑),而對(duì)外界暴露的則是接口類(UserService.java),那么對(duì)于客戶端調(diào)用的時(shí)侯,需要按照接口類所在路徑進(jìn)行命名空間的定義。
所以在發(fā)布之前我們要在業(yè)務(wù)類(UserServiceImpl.java)上增加注解,指定命名空間,然后再進(jìn)行發(fā)布,
那么我們最終在加上(圖一)方框箭頭所指代碼情況下,發(fā)布服務(wù)的結(jié)果為下圖(請(qǐng)看圖三):

五、(發(fā)布服務(wù))接口類,業(yè)務(wù)類代碼都已經(jīng)準(zhǔn)備好,那么我接下來我就要對(duì)webservice服務(wù)進(jìn)行發(fā)布:
代碼如下:
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;
}
}
那么到這里呢,我們的所有的步驟基本完成了,啟動(dòng)spring boot 然后再瀏覽器中輸入url:http://localhost:8080/webservice/test/user?wsdl
可以看到有相關(guān)的wsdl描述信息輸出了,說明服務(wù)已經(jīng)發(fā)布了。
那么這里我又要增加注釋了,請(qǐng)大家注意,我在最初查詢資料,配置demo的時(shí)候,啟動(dòng)以后,發(fā)布時(shí)候總是報(bào)404,網(wǎng)上有很多關(guān)于什么端口沖突等說法,我試過后,根本不是那一回事,然后我無意中嘗試了一下,在url地址處加入工程名,結(jié)果,問題解決了。
因此請(qǐng)大家注意:在測試發(fā)布服務(wù)的時(shí)候,你在瀏覽器中輸入的url地址應(yīng)該是:http://localhost:8080/你的工程名/test/user?wsdl;
然后就是發(fā)布結(jié)果如下圖(見圖四):

到此為止,我們的服務(wù)發(fā)布成功了。
六、調(diào)用服務(wù)
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 為接口中定義的方法名稱 張三為傳遞的參數(shù) 返回一個(gè)Object數(shù)組
Object[] objects=client.invoke("getUser","411001");
//輸出調(diào)用結(jié)果
System.out.println("*****"+objects[0].toString());
}
}
七、最后附上我的工程結(jié)構(gòu)圖(見圖五):

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
數(shù)組在java中的擴(kuò)容的實(shí)例方法
在本篇文章里小編給大家分享的是一篇關(guān)于數(shù)組在java中的擴(kuò)容的實(shí)例方法內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。2021-01-01
Java設(shè)計(jì)模式之命令模式(Command模式)介紹
這篇文章主要介紹了Java設(shè)計(jì)模式之命令模式(Command模式)介紹,本文講解了Command模式的定義、如何使用命令模式等內(nèi)容,需要的朋友可以參考下2015-03-03
詳解spring-boot集成elasticsearch及其簡單應(yīng)用
本篇文章主要介紹了詳解spring-boot集成elasticsearch及其簡單應(yīng)用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
基于java SSM springboot實(shí)現(xiàn)景區(qū)行李寄存管理系統(tǒng)
這篇文章主要介紹了基于java SSM springboot實(shí)現(xiàn)的景區(qū)行李寄存管理系統(tǒng),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-08-08
@PathVariable為空時(shí)指定默認(rèn)值的操作
這篇文章主要介紹了@PathVariable為空時(shí)指定默認(rèn)值的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-02-02
Java使用原型模式展現(xiàn)每日生活應(yīng)用案例詳解
這篇文章主要介紹了Java使用原型模式展現(xiàn)每日生活應(yīng)用案例,較為詳細(xì)的分析了原型模式的概念、原理及Java使用原型模式展現(xiàn)每日生活案例的相關(guān)操作步驟與注意事項(xiàng),需要的朋友可以參考下2018-05-05

