• SpringBoot整合WebService(服务端+客户端)


    SpringBoot整合WebService(服务端+客户端)

    文章目录

    一、服务端

    本项目通过SpringBoot+Mybatis整合WebService,实现服务端接收客户端传入的数据并将其写入数据库等功能,

    1.项目结构

    image-20220521162053648

    2.创建好SpringBoot项目后导入Maven依赖

    直接把全部换成我的

    
            
                org.springframework.boot
                spring-boot-starter
            
    
            
            
                org.springframework.boot
                spring-boot-starter-web
            
    
            
                org.springframework.boot
                spring-boot-starter-test
                test
                
                    
                        org.junit.vintage
                        junit-vintage-engine
                    
                
            
    
            
            
                org.springframework.boot
                spring-boot-starter-web-services
            
    
    
            
                org.apache.cxf
                cxf-rt-frontend-jaxws
                3.2.0
            
            
                org.apache.cxf
                cxf-rt-transports-http
                3.2.0
            
            
                org.apache.cxf
                cxf-core
                3.3.5
            
            
                org.apache.cxf
                cxf-rt-transports-http
                3.2.4
            
    
            
                org.mybatis.spring.boot
                mybatis-spring-boot-starter
                2.1.4
            
            
                mysql
                mysql-connector-java
                runtime
            
            
                org.projectlombok
                lombok
            
    
        
    
    • 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
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    3.建一个pojo包存放实体类User

    import lombok.AllArgsConstructor;
    import lombok.Data;
    
    @Data
    @AllArgsConstructor
    public class User {
    
        private Integer id;
        private String userId;
        private String userName;
       
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    4.建一个service包存放服务类

    UserService

    package cn.edu.usts.sbmpservice.service;
    
    import cn.edu.usts.sbmpservice.pojo.User;
    
    import javax.jws.WebParam;
    import javax.jws.WebService;
    import java.text.ParseException;
    
    @WebService(name = "UserService", // 暴露服务名称
            targetNamespace = "http://service.sbmpservice.usts.edu.cn"// 命名空间,一般是接口的包名倒序
    )
    public interface UserService {
    
        int addUser(User user);
        User queryUser(Integer id);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    UserServiceImpl接口实现类

    package cn.edu.usts.sbmpservice.service.impl;
    
    
    import cn.edu.usts.sbmpservice.dao.UserDao;
    import cn.edu.usts.sbmpservice.dao.YljgjxcDao;
    import cn.edu.usts.sbmpservice.pojo.User;
    import cn.edu.usts.sbmpservice.pojo.Yljgjxc;
    import cn.edu.usts.sbmpservice.service.UserService;
    import cn.edu.usts.sbmpservice.utils.util;
    import org.springframework.beans.factory.annotation.Autowired;
    
    import javax.jws.WebService;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.List;
    
    //@Component
    @WebService(serviceName = "UserService", // 与接口中指定的name一致
            targetNamespace = "http://service.sbmpservice.usts.edu.cn", // 与接口中的命名空间一致,一般是接口的包名倒
            endpointInterface = "cn.edu.usts.sbmpservice.service.UserService"// 接口地址
    )
    public class UserServiceImpl implements UserService {
    
            @Autowired
            private UserDao userDao;
    
            @Override
            public int addUser(User user ){
    
                System.out.println("addUser");
    
                return userDao.addUser(user);
            }
            @Override
            public User queryUser(Integer id){
                System.out.println("queryUser"+" "+id);
                User user = userDao.queryUser(id);
                System.out.println(user);
                return userDao.queryUser(id);
            }
    
    }
    
    • 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
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    5.建一个dao层

    UserDao 处理数据

    package cn.edu.usts.sbmpservice.dao;
    
    import cn.edu.usts.sbmpservice.pojo.User;
    import org.apache.ibatis.annotations.Mapper;
    import org.springframework.stereotype.Repository;
    
    @Mapper
    @Repository
    public interface UserDao {
        int addUser(User user);
        User queryUser(Integer id);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    6.在resources目录下建立一个mapper文件夹

    UserDao.xml

    
    
    
        
            insert into user.user(userId,userName) values (#{userId},#{userName})
        
    
        
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    7.配置数据库

    将application文件后缀改成yml格式,然后根据自己的情况配置数据库和端口号

    mybatis:
      type-aliases-package: cn.edu.usts.sbmpservice.pojo
      mapper-locations: classpath:mapper/*.xml
    spring:
      datasource:
        username: root
        password: root
        url: jdbc:mysql://localhost:3306?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
    
    
    server:
      port: 8081
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    8.配置并发布WebService(重中之重)

    新建一个config目录,存放配置文件

    startclass.java

    package cn.edu.usts.sbmpservice.config;
    
    import cn.edu.usts.sbmpservice.service.UserService;
    import cn.edu.usts.sbmpservice.service.impl.UserServiceImpl;
    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 javax.xml.ws.Endpoint;
    
    @Configuration
    public class StartClas {
    
        @Bean(name = Bus.DEFAULT_BUS_ID)
        public SpringBus springBus() {
            return new SpringBus();
        }
    
        @Bean(name = "wsBean")
        public ServletRegistrationBean dispatcherServlet() {
            ServletRegistrationBean wbsServlet = new ServletRegistrationBean(new CXFServlet(), "/ws/*");
            return wbsServlet;
        }
    
        @Bean
        public UserService userService() {
            return new UserServiceImpl();
        }
    
        @Bean
        public Endpoint endpointPurchase(SpringBus springBus, UserService userService) {
            EndpointImpl endpoint = new EndpointImpl(springBus(), userService());
            endpoint.publish("/api");
            System.out.println("服务发布成功!地址为:http://localhost:8081/ws/api?wsdl");
            return endpoint;
    
    
        }
    }
    
    • 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
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    9.发布WebService服务

    image-20220521160910920

    服务发布成功,打开浏览器输入地址

    image-20220521161049487

    出现如图所示内容表示服务发布成功,图片内容是wsdl(网络服务描述语言,Web Services Description Language),用于描述 Web Services 以及如何对它们进行访问.接下来就可以编写客户端了。

    二、客户端

    客户端调用WebService接口有很多种方法,这里只展示两种,推荐使用第一种

    1.service编程调用方式

    1.1目录结构

    需要将服务端的pojo和service文件同步到客户端

    image-20220521162130729

    1.2调用WebService

    package cn.edu.usts;
    
    import cn.edu.usts.pojo.User;
    import cn.edu.usts.service.UserService;
    
    import javax.xml.namespace.QName;
    import javax.xml.ws.Service;
    import java.net.MalformedURLException;
    import java.net.URL;
    
    public class Client {
        public static void main(String[] args) throws MalformedURLException {
            System.setProperty("javax.xml.bind.JAXBContext", "com.sun.xml.internal.bind.v2.ContextFactory");
            //创建WSDL的URL
            URL url = new URL("http://localhost:8080/ws/api?wsdl");
            // 指定命名空间和服务名称
            QName qName = new QName("http://service.sbmpservice.usts.edu.cn", "UserService");
            Service service = Service.create(url, qName);
            // 通过getPort方法返回指定接口
            UserService myServer = service.getPort(UserService.class);  // 方法1
    //        UserService myServer = service.getPort(new QName("http://serviceImpl.service.usts.edu.cn/", "UserServiceImplPort"), UserService.class); // 方法2
    
            // 调用方法 获取返回值
            User user1 = new User(2,"tom");
            myServer.addUser(user1);
            User user = myServer.queryUser(2);
            System.out.println(user.toString());
        }
    
    }
    
    • 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

    编译

    image-20220521163519950

    客户端如图所示。数据插入成功,查询成功,成功调用web Service接口

    image-20220521163638000

    服务端如图所示。成功接收到客户端发来的数据并将其写入数据库

    image-20220521163721657

    数据库如图所示,成功插入数据

    2.使用WSDL生成本地客户端代码调用WebService

    该种方式使用简单,但一些关键的元素在代码生成时写死到生成代码中,不方便维护,所以仅用于测试。

    2.1 生成本地客户端代码

    新建一个项目,直接在项目中生成客户端代码(不需要在别的地方生成再复制过来)

    打开终端

    image-20220521164619648

    进入到src/main/java/…目录下,使用wsimport 命令,生成客户端代码

     wsimport -keep -extension http://localhost:8080/ws/api?wsdl
    
    • 1

    image-20220521165028333

    回车,然后就可以在目录中看到生成的客户端代码

    image-20220521165201388

    2.2 调用WebService服务

    public class app {
        public static void main(String[] args) {
    
            //创建服务访问点集合的对象
            UserService_Service has = new UserService_Service();
            //获取服务实现类
            //根据服务访问点的集合中的服务访问点的绑定对象来获得绑定的服务类
            UserService soap = has.getUserServiceImplPort();
    
            //调用服务
            User user = soap.queryUser(2);
            System.out.println(user.toString());
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    三、问题及解决方案

    1.Exception in thread “main” com.sun.xml.internal.ws.fault.ServerSOAPFaultException

    image-20220521165839981

    使用service编程调用接口时报错,在网上查资料说是webservice内部jar版本与现在所用的jdk的jar有冲突,需要设置下系统属性,在代码中加入

    System.setProperty("javax.xml.bind.JAXBContext", "com.sun.xml.internal.bind.v2.ContextFactory");
    
    • 1

    2.A query was run and no Result Maps were found for the Mapped Statement

    原因:在服务端的mapper中忘记了指定resultType属性

    image-20220521170444116

    先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

  • 相关阅读:
    一个c程序的内存分布
    kafka—消费者
    python将xml格式文件转成png或者pdf格式
    git 重置到某次提交
    使用标准信号检测 VM振弦采集模块测量精度修正
    面试经典150题——Day6
    win11 Windows hello录入指纹失败解决方法
    [配置] 安卓 | 将微信公众号文章保存到Notion
    几种常用XML文档解析方案的使用操作
    手把手教你搭建android模块化项目框架(十二)——实现自定义view的一些小技巧~
  • 原文地址:https://blog.csdn.net/m0_67403013/article/details/126115050