详解Spring boot+CXF开发WebService Demo

网友投稿 242 2023-05-15


详解Spring boot+CXF开发WebService Demo

最近工作中需要用到webservice,而且结合spring boot进行开发,参照了一些网上的资料,配置过程中出现的了一些问题,于是写了这篇博客,记录一下我这次spring boot+cxf开发的webservice的配置过程,仅供参考。

一、本次开发除了用到spring boot基础jar包外,还用到了cxf相关jar包:

org.apache.cxf

cxf-rt-frontend-jaxws

3.1.6

org.apache.cxf

cxf-rt-transports-http

3.1.6

二、首先我们创建一个实体类,内容是关于用户信息的查询和记录:

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 cnhttp://.paybay.demo.service.impl;

import java.util.Date;

import java.util.HashMap;

import java.util.Map;

import jMMxhYjavax.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 userMap = new HashMap();

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;

iMMxhYjmport 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());

}

}

七、最后附上我的工程结构图(见图五):


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:基于angular实现三级联动的生日插件
下一篇:详解微信小程序 相对定位和绝对定位
相关文章

 发表评论

暂时没有评论,来抢沙发吧~