微服务-微信公众号 【Git地址】https://gitee.com/ying_kevin/springcloud-weixin
1、项目结构
本教程使用的方式是每个微服务作为一个独立项目开发,而不是使用一个聚合工程的方式。所以,现在先搭建我们的第一个微服务,该项目包含以下几个子工程:
weixin-dependencies:版本依赖控制
weixin-service:微信服务接口实现
weixin-service-api:微信服务暴露接口
2、创建项目
创建pom父工程springcloud-weixin:添加springBoot、springCloud、springCloudAlibaba版本依赖,以及引入自定义的工具类commons-api和commons-core,
commons项目传送门,依赖如下所示,该依赖不是最终版本,最新版本请关注项目git地址
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.4.RELEASE</version>
<relativePath/>
</parent>
<groupId>com.kevin</groupId>
<artifactId>weixin-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>weixin-dependencies</module>
<module>weixin-service</module>
<module>weixin-service-api</module>
</modules>
<properties>
<java.version>1.8</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.2.4.RELEASE</spring-boot.version>
<spring-cloud.version>Hoxton.SR1</spring-cloud.version>
<spring-cloud-alibaba.version>2.2.0.RELEASE</spring-cloud-alibaba.version>
<kevin-commons.version>1.0.0-SNAPSHOT</kevin-commons.version>
<mybatis.version>2.1.1</mybatis.version>
<weixin-java-mp.version>3.6.0</weixin-java-mp.version>
<swagger.version>1.7.0.RELEASE</swagger.version>
</properties>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<name>kevin</name>
<email>1136069753@qq.com</email>
</developer>
</developers>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.kevin</groupId>
<artifactId>commons-dependencies</artifactId>
<version>${kevin-commons.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!--springboot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 集成commons工具类 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<optional>true</optional>
</dependency>
<!-- 集成lombok 框架 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--文档管理swagger-->
<dependency>
<groupId>com.spring4all</groupId>
<artifactId>swagger-spring-boot-starter</artifactId>
<version>${swagger.version}</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<!--自定义工具类-->
<dependency>
<groupId>com.kevin</groupId>
<artifactId>commons-api</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.kevin</groupId>
<artifactId>commons-core</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>
创建jar子工程weixin-service-api:该工程主要是提供微服务接口。举例说明一下:如果一个微服务项目由多个公司开发,那么各微服务间使用RPC远程调用接口时,提供方只用将该工程打成一个jar包给调用方调用,避免了业务代码的直接暴露。该项目主要依赖已经在父工程引用,最新版请关注项目git地址
创建jar子工程weixin-service:该工程为业务核心代码,遵循mvc三层架构,实现接口业务逻辑。该项目为微信公众号,那么我们引入微信公众号开源框架weixin-java-mp,类似的框架还有很多,不局限使用这一个。最新版请关注项目git地址
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>weixin-parent</artifactId>
<groupId>com.kevin</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>weixin-service</artifactId>
<packaging>jar</packaging>
<properties>
<docker.image.prefix>kevin-weixin</docker.image.prefix>
<docker.host>http://192.168.101.10:2375</docker.host>
</properties>
<dependencies>
<!--微信服务接口-->
<dependency>
<groupId>com.kevin</groupId>
<artifactId>weixin-service-api</artifactId>
<version>1.0.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<!--springBoot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- 集成aop -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!--健康检查依赖此包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--nacos注册中心-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--nacos配置中心-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--mysql连接驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.version}</version>
</dependency>
<!--微信公众号框架 如果xstream版本不一致,可排除后强制依赖-->
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-mp</artifactId>
<version>${weixin-java-mp.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!-- 指定该Main Class为全局的唯一入口 -->
<mainClass>com.kevin.weixin.WeixinApplication</mainClass>
<layout>ZIP</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal><!--可以把依赖的包都打包到生成的Jar包中-->
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
创建pom子工程weixin-dependencies:该工程主要做版本的依赖控制。依赖如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.kevin</groupId>
<artifactId>weixin-dependencies</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>weixin dependencies</name>
<description>weixin dependencies</description>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.kevin</groupId>
<artifactId>weixin-service-api</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
3、全局异常处理
项目中如何接入commons-api全局异常处理,请看文档开源项目【commons】一 || 开发文档,本项目中接入代码如下所示:
@Order(Integer.MAX_VALUE - 1)
@RestControllerAdvice
public class GlobalException extends GlobalExceptionHandler {
}
在weixin-service工程的exception包下,新增了一个全局异常DuplicateKeyException,统一处理数据库主键冲突异常。
4、整合swagger2
Swagger2可以用于生成、描述、调用和可视化RESTful风格的Web服务,可在线自动生成接口文档,对于前后端分离项目,无疑是一个很好的解决方案。在springboot中接入swagger2需要添加下面依赖:
<dependency>
<groupId>com.spring4all</groupId>
<artifactId>swagger-spring-boot-starter</artifactId>
<version>1.7.0.RELEASE</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
创建swagger的配置启动类,实现SwaggerResourcesProvider,添加以下注解:
Configuration:让spring加载该配置类
EnableSwagger2Doc:启用swagger
ConditionalOnExpression:可以动态配置是否开启swagger,生产环境是不允许使用,所以添加该注解便于不同环境下切换。
Primary:优先选择用该注解的bean
@Configuration
@Primary
@ConditionalOnExpression("${options.swagger:true}")
@EnableSwagger2Doc
public class SwaggerConfig implements SwaggerResourcesProvider {
@Override
public List<SwaggerResource> get() {
List resources = new ArrayList<>();
resources.add(swaggerResource("weixin-service", "/v2/api-docs", "2.0"));
return resources;
}
private SwaggerResource swaggerResource(String name, String location, String version) {
SwaggerResource swaggerResource = new SwaggerResource();
swaggerResource.setName(name);
swaggerResource.setLocation(location);
swaggerResource.setSwaggerVersion(version);
return swaggerResource;
}
}
在配置文件中配置swagger的信息,主要配置内容如下所示,更多的配置信息可以查看官方文档,以下列举几个描述:
swagger.base-package=swagger解析包的路径
swagger.title=标题
swagger.description=描述
swagger.terms-of-service-url=服务条款URL
swagger.version=版本
swagger.contact.name=联系人
swagger.contact.email=联系人email
swagger.contact.url=联系人url
swagger.license=许可证
swagger.license-url=许可证URL
swagger.ui-config.json-editor=true #是否启用json编辑器
swagger.enabled=true #是否开启swagger
swagger:
base-package: com.kevin.weixin.service
title: 微信公众号接口
description: 由kevin版权所有
version: 1.0
terms-of-service-url: www.kevinying.club
contact:
name: kevin
email: 1136069753@qq.com
ui-config.json-editor: true
是否开启swagger有两种实现方式:
- 第一:使用swagger.enable配置。使用该方式,在nacos中不可以动态刷新。
- 第二:使用ConditionalOnExpression注解。
配置完成后,运行项目,输入swagger地址:ip:端口/swagger-ui.html,可以看到我们配置的信息也显示了,接下来可以使用swagger测试我们的接口了。