• SpringBoot+cxf发布WebService


    介绍

    公司遗留老系统是一个产品化的ERP,只支持webService的发布,且调用方仅能调用webService.ERP发布的webservice依赖了很多产品化的其他组件,现在想脱离这些组件。于是直接连数据库,然后自己写webService来调用。因为本机Gradle版本是4.9,所以spring boot无法用最新版本。

    环境介绍

    • jdk:11
    • gradle:4.9
    • springBoot:2.1.3
    • apache-cxf:3.2.4
    • lombok
    • h2

    测试过程设计

    • 使用h2数据库建表,保存几个测试数据
    • 发布2个webservice接口,一个是生成测试数据的(insertFooBean),一个是查询数据的(queryFooBean)
    • 考虑spring boot与cxf的集成
    • 考虑jdk11下jax-ws相关包被移除的问题

    废话少说上代码

    gradle的配置

    plugins {
    	id 'org.springframework.boot' version '2.1.3.RELEASE'
    	id 'io.spring.dependency-management' version '1.0.10.RELEASE'
    	id 'java'
    }
    
    group = 'com.jde.ws'
    version = '0.0.1-SNAPSHOT'
    sourceCompatibility = '11'
    
    configurations {
    	compileOnly {
    		extendsFrom annotationProcessor
    	}
    }
    
    repositories {
    	maven {
    		url 'https://maven.aliyun.com/repository/public/'
    	}
    	mavenCentral()
    }
    
    dependencies {
    	implementation 'org.springframework.boot:spring-boot-starter-web'
    	implementation 'org.springframework.boot:spring-boot-starter-jdbc'
    
    	implementation 'org.apache.cxf:cxf-spring-boot-starter-jaxws:3.2.4'
    	implementation 'com.sun.xml.ws:jaxws-ri:2.3.3'//javax.xml.ws相关包
    	implementation 'javax.xml.ws:jaxws-api:2.3.1' //javax.jws相关包
    
    	compileOnly 'org.projectlombok:lombok'
    	runtimeOnly 'com.h2database:h2'
    	annotationProcessor 'org.projectlombok:lombok'
    	testImplementation('org.springframework.boot:spring-boot-starter-test') {
    		exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    	}
    }
    
    test {
    	useJUnitPlatform()
    }
    
    

    spring boot配置

    application.properties

    spring.datasource.url=jdbc:h2:mem:testdb
    spring.datasource.username=sa
    spring.datasource.password=sa
    
    #声明h2
    spring.datasource.platform=h2
    #开启web访问
    spring.h2.console.settings.web-allow-others=true
    #配置console的URI
    spring.h2.console.path=/h2
    #配置跟随程序启动
    spring.h2.console.enabled=true
    

    建表及数据的sql文件,data.sql与schema.sql

    INSERT INTO FOO (BAR) VALUES ('aaa');
    
    CREATE TABLE FOO (ID INT IDENTITY, BAR VARCHAR(64));
    

    spring boot启动类,初始化建表

    package com.jde.ws.jdebpmws;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.Bean;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
    import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
    
    import javax.sql.DataSource;
    
    @SpringBootApplication
    @Slf4j
    public class JdebpmwsApplication {
    
    	@Bean
    	@Autowired
    	public SimpleJdbcInsert simpleJdbcInsert(JdbcTemplate jdbcTemplate) {
    		return new SimpleJdbcInsert(jdbcTemplate)
    				.withTableName("FOO").usingGeneratedKeyColumns("ID");
    	}
    
    	@Bean
    	@Autowired
    	public NamedParameterJdbcTemplate namedParameterJdbcTemplate(DataSource dataSource) {
    		return new NamedParameterJdbcTemplate(dataSource);
    	}
    
    	public static void main(String[] args) {
    		SpringApplication.run(JdebpmwsApplication.class, args);
    	}
    
    }
    
    

    接口声明及实现类

    FooService

    package com.jde.ws.jdebpmws.service;
    
    import javax.jws.WebMethod;
    import javax.jws.WebParam;
    import javax.jws.WebService;
    
    
    @WebService(targetNamespace = "http://jdebpmws.ws.jde.com/")
    public interface FooService {
    
    	@WebMethod
    	String queryFooBean(@WebParam(name = "id") Long id);
    
    	@WebMethod
    	String insertFooBean();
    }
    
    

    FooServiceImpl

    package com.jde.ws.jdebpmws.service.impl;
    
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.jde.ws.jdebpmws.Foo;
    import com.jde.ws.jdebpmws.FooDao;
    import com.jde.ws.jdebpmws.service.FooService;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import javax.jws.WebService;
    
    
    @WebService(serviceName = "fooService"
    		, targetNamespace = "http://jdebpmws.ws.jde.com/"
    		, endpointInterface = "com.jde.ws.jdebpmws.service.FooService")
    @Service
    @Slf4j
    public class FooServiceImpl implements FooService {
    
    	@Autowired
    	private FooDao fooDao;
    
    
    	@Override
    	public String queryFooBean(Long id) {
    		ObjectMapper mapper = new ObjectMapper();
    		Foo foo = fooDao.queryFooBean(id);
    		String resJson = "{"code":"%s", "data":%s}";
    		if (null != foo) {
    			try {
    				String fooJson = mapper.writeValueAsString(foo);
    				resJson = String.format(resJson, "200", fooJson);
    			} catch (Exception e) {
    				resJson = String.format(resJson, "0", e.toString());
    				e.printStackTrace();
    				log.error(e.toString());
    			}
    		} else {
    			resJson = String.format(resJson, "0", "");
    		}
    		return resJson;
    	}
    
    
    	@Override
    	public String insertFooBean() {
    		fooDao.insertData();
    		return "OK";
    	}
    }
    
    

    数据库DAO

    FooDao

    package com.jde.ws.jdebpmws;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.jdbc.core.RowMapper;
    import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
    import org.springframework.stereotype.Repository;
    
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.stream.Collectors;
    
    @Slf4j
    @Repository
    public class FooDao {
    	@Autowired
    	private JdbcTemplate jdbcTemplate;
    	@Autowired
    	private SimpleJdbcInsert simpleJdbcInsert;
    
    	public void insertData() {
    		Arrays.asList("b", "c").forEach(bar -> {
    			jdbcTemplate.update("INSERT INTO FOO (BAR) VALUES (?)", bar);
    		});
    		HashMap<String, String> row = new HashMap<>();
    		row.put("BAR", "d");
    		Number id = simpleJdbcInsert.executeAndReturnKey(row);
    		log.info("ID of d: {}", id.longValue());
    	}
    
    	public void listData() {
    		log.info("Count: {}",
    				jdbcTemplate.queryForObject("SELECT COUNT(*) FROM FOO", Long.class));
    		List<String> list = jdbcTemplate.queryForList("SELECT BAR FROM FOO", String.class);
    		list.forEach(s -> log.info("Bar: {}", s));
    		List<Foo> fooList = jdbcTemplate.query("SELECT * FROM FOO", new RowMapper<Foo>() {
    			@Override
    			public Foo mapRow(ResultSet rs, int rowNum) throws SQLException {
    				return Foo.builder()
    						.id(rs.getLong(1))
    						.bar(rs.getString(2))
    						.build();
    			}
    		});
    		fooList.forEach(f -> log.info("Foo: {}", f));
    	}
    
    	public Foo queryFooBean(Long id) {
    		List<Foo> fooList = jdbcTemplate.query("SELECT * FROM FOO", new RowMapper<Foo>() {
    			@Override
    			public Foo mapRow(ResultSet rs, int rowNum) throws SQLException {
    				return Foo.builder()
    						.id(rs.getLong(1))
    						.bar(rs.getString(2))
    						.build();
    			}
    		});
    		Map<Long, Foo> fooMap = fooList.stream().collect(Collectors.toMap(Foo::getId, a -> a, (k1, k2) -> k1));
    		return fooMap.get(id);
    
    	}
    }
    
    

    测试的实体对象Foo

    package com.jde.ws.jdebpmws;
    
    import lombok.Builder;
    import lombok.Data;
    
    @Data
    @Builder
    public class Foo {
    	private Long id;
    	private String bar;
    }
    
    

    cxf的配置类

    CxfConfig

    package com.jde.ws.jdebpmws.config;
    
    
    import com.jde.ws.jdebpmws.service.FooService;
    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;
    
    	@Autowired
    	private FooService fooService;
    
    	@Bean
    	public Endpoint fooServiceEndpoint() {
    		EndpointImpl endpoint = new EndpointImpl(bus, fooService);
    		endpoint.publish("/fooService");
    		return endpoint;
    	}
    }
    
    

    使用SOAP-UI测试

    测试添加数据的接口,截图如下:

    查看数据库中的数据,截图如下:

    测试查询数据接口,截图如下:

    完整测试demo

    https://github.com/canGBean/springboot_cxf_webservice_demo

  • 相关阅读:
    mq和kafaka架构方面对比高可用性
    一 mq简介
    gtibook 写api文档
    StackExchang.Redis 不稳定
    Log4Net 帮助类
    Android学习之Recyclerview
    《程序员修炼之道--从小工到专家》读书小计
    Xcode7 使用WebView loadRequest发送HTTP请求的问题
    ashx中应用HttpContext.Current.Session ,呈现未将对象引用设置到实例(转)
    Oracle 删除重复数据只留一条【转】
  • 原文地址:https://www.cnblogs.com/GYoungBean/p/13806497.html
Copyright © 2020-2023  润新知