springboot-WSDL服务端

springboot实现webservice生成wsdl

1.核心技术选型

  • springboot 2.7.0
  • apache CXF 3.5.0

2.项目结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EpzWPWRb-1667378754339)(java-WSDL服务端.assets\1667370354458.png)]

3.项目搭建

搭建工具:maven

搭建步骤:

​ 1.搭建maven项目

​ 2.编写pom导入依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-spring-boot-starter-jaxws</artifactId>
        <version>3.5.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-frontend-jaxws</artifactId>
        <version>3.5.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-transports-http</artifactId>
        <version>3.5.0</version>
    </dependency>

</dependencies>

3.编写启动类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class WsApplication {

    public static void main(String[] args) {
        SpringApplication.run(WsApplication.class, args);
    }

}

​ 4.application.yml基本配置

​ src\resouse目录下创建文件application.yml

​ 写入配置:

server:
  port: 8888  # 发布端口
spring:
  main:
    allow-bean-definition-overriding: true
  application:
    name: chengkz-boot-cxf  
cxf:   
  path: /ws  # webservice的发布url路径  例:http://127.0.0.1:8888/ws/....

4.定义要发布的业务接口

在service目录下创建接口,定义方法

public interface FileService {
    public byte[] sealValidation( byte[] pdfData, String filename);
}

注意

  • 1.方法参数顺序对应发布后第三者调用所需的方法参数顺序

  • 2.方法参数类型对应发布后第三者调用所需的参数类型

  • 3.方法名对应发布后第三方调用的方法名

5.编写接口的实现类

将逻辑代码写进实现方法

@WebService  //必要注解
@Service    //必要注解
@Slf4j      //日志注解
@AutoPublishWS(publishPath = "FileService") //动态发布配置必要注解,具体作用见下文
public class FileServiceImpl implements FileService {
    @Override
    @WebMethod  //必要注解
    @WebResult(name = "fileResult") //自定义服务结果名 
    public byte[] sealValidation(byte[] pdfData, String filename) {
        //在这里模拟接收base64编码的二进制文件
        byte[] data = Base64.getDecoder().decode(pdfData);
        log.info("处理文件:" + filename);
        //返回
        return data;
    }

}

6.服务的发布与配置

服务的发布有两种方式:

6.1 静态发布

编写cxf配置类 不建议接口服务较多时使用

import com.ckz.ws.service.impl.CalculatorServiceImpl;
import com.ckz.ws.service.impl.MsgServiceImpl;
import com.ckz.ws.service.impl.FileServiceImpl;
import org.apache.cxf.Bus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.xml.ws.Endpoint;

@Configuration  //若采用动态发布请注释掉这个注解
public class CxfConfig {
    @Autowired
    private Bus bus;

    //每有一个webservice接口就需要如下形式
    @Autowired
    private CalculatorServiceImpl calculatorService;
    @Bean
    public Endpoint calculatorServer() {
        EndpointImpl endpoint = new EndpointImpl(bus,calculatorService);
        endpoint.publish("/calculator");//在这里设置发布的地址  http://ip:port/xxx/calculator
        return endpoint;
    }
    
    
    //
    
    @Autowired
    private FileServiceImpl pdfService;
     @Bean
    public Endpoint pdfServer() {
        EndpointImpl endpoint = new EndpointImpl(bus,msgService);
        endpoint.publish("/fileServer");
        return endpoint;
    }
    
    @Autowired
    private MsgServiceImpl msgService;

 	@Bean
    public Endpoint msgServer() {
        EndpointImpl endpoint = new EndpointImpl(bus,pdfService);
        endpoint.publish("/msgServer");
        return endpoint;
    }
   

   

   
}

6.2 动态发布

在这里搬运的B站大佬 up主:jinshengyuanok
他的视频有更详细的教学,希望大家给他三连

1.编写自动注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface AutoPublishWS {
    String publishPath();
}

2.编写自动发布配置类

里面涉及到的自定义注解名要与你自定义的注解名保持一致

写法基本固定写死,注解名未改动可直接使用

package com.ckz.ws.config;

import com.ckz.ws.annotation.AutoPublishWS;
import lombok.extern.slf4j.Slf4j;
import org.apache.cxf.Bus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

import static org.apache.tomcat.jni.Buffer.address;

@Slf4j
@Component
@Order(1)
public class AutoPublishWSEndpoint implements ApplicationRunner {


    //取出WS的根路径
    @Value("${cxf.path}")
    public String cxfPath;
    //取出AppName
    @Value("${spring.application.name}")
    public String appName;
    //注入CXF Bus
    @Autowired
    private Bus bus;
    //注入Spring Web中Servlet上下文Web容器
    @Autowired
    private WebApplicationContext webApplicationContext;
    @Override
    public void run(ApplicationArguments args) throws Exception {

        log.info("AutoPublishWSEndpoint===发布开始");
//根据注解获取beanNames
        String[] beanNames =
                webApplicationContext.getBeanNamesForAnnotation(AutoPublishWS.class);
        EndpointImpl endpoint;
        List<String> cxfPathList = new ArrayList<>();
        for (String beanName : beanNames) {
//根据beanName获取属性名
            String publishPath =
                    webApplicationContext.getType(beanName).getAnnotation(AutoPublishWS.class).publishPath();
//发布WebService接口
            endpoint = new EndpointImpl(bus,
                    webApplicationContext.getBean(beanName));
            endpoint.publish(publishPath);
            cxfPathList.add(publishPath);
            log.info(String.format("%s", publishPath));
        }
        log.info("AutoPublishWSEndpoint===发布结束");
        Environment environment = webApplicationContext.getEnvironment();
        address(environment, cxfPathList);

    }

    private void address(Environment environment, List<String> cxfPathList) {

        try {
            String ip = InetAddress.getLocalHost().getHostAddress();
            String port = environment.getProperty("server.port");
            String path = environment.getProperty("server.servlet.contextpath");
            if (path == null) {
                path = "";
            }
            log.info("\n-------------------------------------------------------- --\n\t" +
                    "Application " + appName + " is running! Access URLs:\n\t" +
                            "Local: \t\thttp://localhost:" + port + path + "/\n\t" +
                            "External: \thttp://" + ip + ":" + port + path + "/" + "\n---------------------------------------------------------- ");
            if (cxfPathList.size() > 0) {
                StringBuilder logStr = new StringBuilder();
                logStr.append("\n\tWSDL URLS:\n\t");
                String finalPath = path;
                cxfPathList.forEach(s -> {
                    logStr.append("\t\thttp://localhost:" + port + finalPath +
                            cxfPath + "/" + s + "?wsdl\n\t");
                    logStr.append("\t\thttp://" + ip + ":" + port + finalPath +
                            cxfPath + "/" + s + "?wsdl\n\t");
                });
                log.info(logStr.toString());
            }
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }



}

3.在要发布service实现类加上注解

如上文实现类介绍处

@AutoPublishWS(publishPath = "FileService")  //publishPath为你要设置的接口服务url路径
//http:\\ip:port\xxx\FileService?wsdl

7.项目打包

该项目基于springboot

建议使用idea插件mavenHelper打包

打包步骤

右键项目根包

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eVVLREWJ-1667378754341)(java-WSDL服务端.assets\1667374575490.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EluzV98f-1667378754343)(java-WSDL服务端.assets\1667374666241.png)]

8.基于原有项目新增wenservice接口

项目(动态发布模式)启动成功后会输出具体url信息 //注意: 注释掉静态发布配置类的@Configuration注解

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PV9ShysW-1667378754344)(java-WSDL服务端.assets\1667375782022.png)]

8.1 若有新类别webservice服务

在service目录下新建接口

具体操作与注意详见

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bI9i67qt-1667378754345)(java-WSDL服务端.assets\1667375070580.png)]

8.2 若只有新webservice方法

1.在对应的webservice接口里声明

2.在对应webservice实现类里实现方法

其注意事项与具体操作详见

8.3 模板接口与模板接口实现类

1.模板接口

package com.ckz.ws.service;

public interface XxxxService { //在这里 "XxxxService" 建议以这种格式自定义
      
    /**
    *方法声明
    *[returnType] 返回值类型  
    *[method name] 方法名
    *[argType] [arg name] ... 参数类型 参数名  。。。
    */
    public [returnType] [method name]( [argType] [arg name], ...);
}

2.实现类接口

package com.ckz.ws.service.impl;

import com.ckz.ws.annotation.AutoPublishWS;
import com.ckz.ws.service.FileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.jws.WebMethod;
import javax.jws.WebResult;
import javax.jws.WebService;
import java.util.Base64;

@WebService
@Service
@Slf4j
@AutoPublishWS(publishPath = "XxxService")
public class FileServiceImpl implements FileService {
    @Override
    @WebMethod
    @WebResult(name = "xxxResult")
    public [returnType] [method name]( [argType] [arg name], ...) {
        //业务逻辑
        //byte[] data = Base64.getDecoder().decode(pdfData);
        //log.info("处理文件:" + filename);
        //return data;
    }

}

附录

MavenHelper安装

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dylM0ovT-1667378754346)(java-WSDL服务端.assets\1667377206589.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oSoaykYT-1667378754348)(java-WSDL服务端.assets\1667377239233.png)]

最后选择插件压缩包安装

Service {
@Override
@WebMethod
@WebResult(name = “xxxResult”)
public [returnType] [method name]( [argType] [arg name], …) {
//业务逻辑
//byte[] data = Base64.getDecoder().decode(pdfData);
//log.info(“处理文件:” + filename);
//return data;
}

}


## 附录

### MavenHelper安装

[外链图片转存中...(img-dylM0ovT-1667378754346)]

[外链图片转存中...(img-oSoaykYT-1667378754348)]

最后选择插件压缩包安装

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值