详解Spring boot+CXF开发WebService Demo
最近工作中需要用到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()); } }
七、最后附上我的工程结构图(见图五):
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读
-
利用Spring Boot如何开发REST服务详解
-
spring如何集成cxf实现webservice接口功能详解
-
Spring整合CXF webservice restful实例详解
-
详解Spring boot+CXF开发WebService Demo
-
详解使用Spring Boot开发Restful程序
-
spring如何集成cxf实现webservice接口功能详解
-
详解使用Spring Boot开发Restful程序
-
详解Spring Boot实战之Rest接口开发及数据库基本操作
-
详解Spring Boot实战之Rest接口开发及数据库基本操作
-
利用Spring Boot如何开发REST服务详解