服务端工程使用IntellijIDEA开发,IDEA开发环境配置如下:
1、首先配置JDK
安装maven3.3.9,过程略。
关于maven仓库有以下配置方法:
(1)已经有私服地址可在setting.xml中配置私服地址(2)从中央仓库下载maven‐releases 私服账号 私服密码 maven‐snapshots 私服账号 私服密码 nexus * 私服地址
不作任何配置,maven自行从中央仓库下载,也可使用阿里官网Maven库:
(3)使用本地仓库alimaven aliyun maven http://maven.aliyun.com/nexus/content/groups/public central
本教程使用本地仓库配置。在maven的setting.xml文件中配置本地仓库的路径,路径位置不要使用中文,配置例子如下:
在IDEA中选择setting.xml文件,自动找到本地仓库目录 ,如下图:
IDEA可以集成Eclipse的快捷键
如需自定义则点击“copy”复制一份进行修改
idea可以自动优化导入包,但是有多个同名的类调用不同的包,必须自己手动 Alt+Enter 设置
设置idea导入包
自定义自己的代码模板
默认IDEA的提示是区分大小写的,这里设置为提示忽略大小写
Lombok是一个实用的java工具,使用它可以消除java代码的臃肿,Lombok提供一系列的注解,使用这些注解可以不用定义getter/setter、equals、构造方法等,它会在编译时在字节码文件自动生成这些通用的方法,简化开发人员的工作。
项目官方地址:https://www.projectlombok.org/
比如上节创建的UserTest模型,@Data 注解可以自动生成getter/setter方法, @ToString 生成tostring方法。
使用方法:
① 在项目中添加Lombok的依赖作用:项目在编译时根据Lombok注解生成通用方法,依赖如下:
② 在IDEA开发工具中添加Lombok插件org.projectlombok lombok
作用:使用IDEA开发时根据Lombok注解生成通用方法,不报错。
修改idea64.exe.vmoptions(64位电脑选择此文件)
一个例子,电脑内存8G,设置如下:
-Xms1024m -Xmx4096m -XX:MaxPermSize=1024m -XX:ReservedCodeCacheSize=1024mNacos服务发现与配置中心
微服务开发需要构建服务发现中心、配置中心,本项目采用Nacos来实现。
详见 Nacos服务发现与配置中心管理
Mybatis Plus本项目数据库使用 mysql-community-5.7,请自行安装MySQL数据库。
本项目持久层采用Mybatis Plus作为技术构架,Mybatis Plus是在Mybatis基础上作了很好的封装,方便系统开发。
学习Mybatis Plus详见 Mybatis-Plus介绍。
导入基础工程将基础工程导入IDEA,如下是基础工程结构图:
| 工程名 | 说明 |
|---|---|
| shanjupay | 闪聚支付父工程 |
| shanjupay-common | 项目通用工程包括:常用工具类和分页信息封装VO等 |
使用客户端连接MySQL,执行 shanjupay-init.sql ,执行脚本自动创建数据库并导入初始数据。
数据库清单如下:
| 数据库名称 | 数据内容 |
|---|---|
| shanjupay_merchant_service | 用户中心数据 |
| shanjupay_transaction | 交易服务数据库 |
备注:数据库、表中的字段以及表关系会在后续开发过程中随用随讲。
搭建项目服务本节搭建如下项目工程:
| 服务名 | 职责 |
|---|---|
| 商户平台应用(shanjupay-merchant-application) | 为前端提供商户管理功能 |
| 商户服务API(shanjupay-merchant-api) | 定义商户服务提供的接口 |
| 商户服务(shanjupay-merchant-service) | 实现商户服务的所有接口 |
三个工程在架构中的位置如下:
在基础工程的基础上创建商户平台应用工程。
1、选中shanjupay工程,右键选择新建Module
2、选择Maven和JDK1.8
3、填写ArtifactId: shanjupay-merchant-application,设置Modoule Name:shanjupay-merchant-application
4、点击Fininsh完成创建
5、添加依赖,完善pom.xml
shanjupay com.shanjupay 1.0-SNAPSHOT 4.0.0 com.shanjupay shanjupay-merchant-application com.alibaba.cloud spring-cloud-starter-alibaba-nacos-config com.alibaba.cloud spring-cloud-starter-alibaba-nacos-discovery com.alibaba.cloud spring-cloud-starter-dubbo org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-logging org.springframework.boot spring-boot-starter-log4j2 org.springframework.boot spring-boot-configuration-processor true org.springframework.boot spring-boot-starter-actuator org.springframework.boot spring-boot-starter-test test io.springfox springfox-swagger2
6、配置bootstrap.yml
server:
port: 57010 #启动端口 命令行注入
max-http-header-size: 100KB
nacos:
server:
addr: 127.0.0.1:8848
spring:
application:
name: merchant-application
main:
allow-bean-definition-overriding: true # Spring Boot 2.1 需要设定
cloud:
nacos:
discovery:
server-addr: ${nacos.server.addr}
namespace: 2aac6f5e-f974-464c-8261-ce06c0566687 #在nacos上新建的空间
cluster-name: DEFAULT
config:
server-addr: ${nacos.server.addr} # 配置中心地址
file-extension: yaml
namespace: 2aac6f5e-f974-464c-8261-ce06c0566687 # 命令行注入
group: SHANJUPAY_GROUP # 聚合支付业务组
ext-config:
-
refresh: true
data-id: spring-boot-http.yaml # spring boot http配置
group: COMMON_GROUP # 通用配置组
#SpringMVC上传文件配置
servlet:
multipart:
#默认支持文件上传.
enabled: true
#支持文件写入磁盘.
file-size-threshold: 0
# 上传文件的临时目录
location:
# 最大支持文件大小
max-file-size: 1MB
# 最大支持请求大小
max-request-size: 30MB
dubbo:
scan:
# dubbo 服务扫描基准包
base-packages: com.shanjupay
protocol:
# dubbo 协议
name: dubbo
port: 20891
registry:
address: nacos://127.0.0.1:8848
application:
qos:
port: 22310 # dubbo qos端口配置 命令行注入
consumer:
check: false
timeout: 3000
retries: -1
logging:
config: classpath:log4j2.xml
7.、 在Nacos中添加spring-boot-http.yaml配置,Group:COMMON_GROUP,这里统一使用dev命名空间,没有此命名空间则在nacos中创建。
#HTTP格式配置
spring:
http:
encoding:
charset: utf-8
force: true
enabled: true
messages:
encoding: UTF-8
#tomcat头信息(用户ip和访问协议)及访问路径配置
server:
tomcat:
remote-ip-header: x-forwarded-for #头信息
protocol-header: x-forwarded-proto
servlet:
context-path: / #[请求路径]
use-forward-headers: true
#服务监控与管理配置,运维相关
management:
endpoints:
web:
exposure:
include: refresh,health,info,env
Nacos配置页面如下所示:
8、在Nacos中添加merchant-application.yaml配置,Group:SHANJUPAY_GROUP
#覆盖访问路径
server:
servlet:
context-path: /merchant
#启用Swagger
swagger:
enable: true
Nacos配置页面如下所示:
9、在resources目录下添加log4j2配置文件:log4j2.xml
log4j2是log4j的改进版本,性能比log4j要高,通常日志配置文件在开发可以调整日志级别,输出详细的日志来跟踪程序的执行。
${project.name} logs [${project.name}][${env:SERVER_PORT}] %date{YYYY-MM-dd HH:mm:ss,SSS} %highlight{%level} [%thread][%file:%line] - %msg%n%throwable
10、添加启动类
- 添加包:com.shanjupay.merchant
- 新建启动类:MerchantApplicationBootstrap
package com.shanjupay.merchant;
//merchant 表示商户
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class MerchantApplicationBootstrap {
public static void main(String[] args) {
SpringApplication.run(MerchantApplicationBootstrap.class, args);
}
}
11、启动服务
访问http://localhost:8848/nacos nacos服务列表,发现shanjupay-merchant-application服务已注册到nacos中。
在基础工程的基础上创建商户服务工程,商户服务工程包括接口和接口实现两个子工程。
1、按上述步骤创建商户服务工程 shanjupay-merchant
2、在 shanjupay-merchant 下创建 shanjupay-merchant-api ,选中shanjupay-merchant工程右键–>New–>Module,填写artifactId和Module Name:shanjupay-merchant-api
3、在 shanjupay-merchant 下创建 shanjupay-merchant-service ,选中 shanjupay-merchant 工程右键–>New–>Module,填写artifactId和Module Name:shanjupay-merchant-service
4、两个工程创建成功后,项目整体目录结构如下所示:
5、完善pom.xml,
shanjupay-merchant-api 模块依赖如下:
shanjupay-merchant com.shanjupay 1.0-SNAPSHOT 4.0.0 com.shanjupay shanjupay-merchant-api com.shanjupay shanjupay-common 1.0-SNAPSHOT
shanjupay-merchant-service 模块依赖
shanjupay-merchant com.shanjupay 1.0-SNAPSHOT 4.0.0 com.shanjupay shanjupay-merchant-service com.alibaba.cloud spring-cloud-starter-alibaba-nacos-config com.alibaba.cloud spring-cloud-starter-alibaba-nacos-discovery com.alibaba.cloud spring-cloud-starter-dubbo org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-logging org.springframework.boot spring-boot-starter-jdbc com.baomidou mybatis-plus-boot-starter com.baomidou mybatis-plus-generator org.mybatis mybatis-typehandlers-jsr310 com.alibaba druid-spring-boot-starter mysql mysql-connector-java org.springframework.boot spring-boot-starter-log4j2 org.springframework.boot spring-boot-configuration-processor true org.springframework.boot spring-boot-starter-actuator org.springframework.boot spring-boot-starter-test test org.apache.commons commons-pool2 org.mapstruct mapstruct-jdk8 org.mapstruct mapstruct-processor ${org.mapstruct.version} org.projectlombok lombok ${org.projectlombok.version}
6、在resources目录下添加日志配置文件:log4j2.xml
7、在resources目录下添加配置文件:bootstrap.yml,将下边配置中namespace的ID替换为之前创建的dev命名空间的ID
bootstrap.yml内容如下
server:
port: 56040 #启动端口 命令行注入
nacos:
server:
addr: 127.0.0.1:8848
spring:
application:
name: merchant-service
main:
allow-bean-definition-overriding: true # Spring Boot 2.1 需要设定
cloud:
nacos:
discovery:
server-addr: ${nacos.server.addr}
namespace: 2aac6f5e-f974-464c-8261-ce06c0566687
cluster-name: DEFAULT
config:
server-addr: ${nacos.server.addr} # 配置中心地址
file-extension: yaml
namespace: 2aac6f5e-f974-464c-8261-ce06c0566687 # 命令行注入
group: SHANJUPAY_GROUP # 聚合支付业务组
ext-config:
- # - 此处不不能删除
refresh: true
data-id: spring-boot-http.yaml # spring boot http配置
group: COMMON_GROUP # 通用配置组
dubbo:
scan:
# dubbo 服务扫描基准包
base-packages: com.shanjupay
protocol:
# dubbo 协议
name: dubbo
port: 20890
registry:
address: nacos://127.0.0.1:8848
application:
qos:
port: 22240 # dubbo qos端口配置 命令行注入
consumer:
check: false
timeout: 90000
retries: -1
logging:
config: classpath:log4j2.xml
8、在Nacos中添加merchant-service.yaml配置,Group:SHANJUPAY_GROUP
#覆盖spring-boot-http.yaml的项目
server:
servlet:
context-path: /merchant-service
9、添加商户中心服务启动类
package com.shanjupay.merchant;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MerchantBootstrap {
public static void main(String[] args) {
SpringApplication.run(MerchantBootstrap.class,args);
}
}
工程测试
通过一个案例“根据Id查询商户”的开发去熟悉项目架构的基本开发方法。
生成代码使用mp的自动生成工程生成entity、mapper等文件。
1、修改生成类中的数据库链接,连接shanjupay_merchant_service数据库
// 商户服务
dataSourceConfig.setUrl("jdbc:mysql://127.0.0.1:3306/shanjupay_merchant_service?serverTimezone=Asia/Shanghai");
2、设置包路径
// 生成包配置
PackageConfig packageConfig = new PackageConfig();
packageConfig.setParent("com.shanjupay");
3、运行生成类,输入模块名:merchant
生成成功:
将生成的entity、mapper拷贝到shanjupay-merchant-service工程
1、在nacos中新建连接池Druid配置:spring-boot-starter-druid.yaml,Group为:COMMON_GROUP,内容如下:
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/oauth?useUnicode=true
username: root
password: root
druid:
initial-size: 5
min-idle: 5
max-active: 20
max-wait: 60000
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
validation-query: SELECt 1 FROM DUAL
test-while-idle: true
test-on-borrow: true
test-on-return: false
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
filter:
stat:
slow-sql-millis: 1
log-slow-sql: true
filters: config,stat,wall,log4j2
web-stat-filter:
enabled: true
url-pattern: mappermapper
@Configuration
@MapperScan("com.shanjupay.**.mapper")
public class MybatisPlusConfig {
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
@Bean
public PerformanceInterceptor performanceInterceptor(){
return new PerformanceInterceptor();
}
}
创建接口
在shanjupay-merchant-api工程下新建商户接口:MerchantService
package com.shanjupay.merchant.api;
import com.shanjupay.merchant.api.dto.MerchantDTO;
public interface MerchantService {
//根据 id查询商户 返回值类型为自定义MerchantDTO
//主要原因:保证MerchantDTO作为数据库表字段一一对应关系
//简单理解为:service接口于dao层接口不同
public MerchantDTO queryMerchantById(Long id);
}
注意:DTO类型的对象作为service层传输的对象。
在shanjupay-merchant-api工程 定义MerchantDTO
package com.shanjupay.merchant.api.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@ApiModel(value = "MerchantDTO", description = "商户信息")
@Data
public class MerchantDTO implements Serializable {
@ApiModelProperty("商户id")
private Long id;
@ApiModelProperty("企业名称")
private String merchantName;
@ApiModelProperty("企业编号")
private String merchantNo;
@ApiModelProperty("企业地址")
private String merchantAddress;
@ApiModelProperty("行业类型")
private String merchantType;
@ApiModelProperty("营业执照")
private String businessLicensesImg;
@ApiModelProperty("法人身份证正面")
private String idCardFrontImg;
@ApiModelProperty("法人身份证反面")
private String idCardAfterImg;
@ApiModelProperty("联系人")
private String username;
@ApiModelProperty("密码")
private String password;
@ApiModelProperty("手机号,关联统一账号")
private String mobile;
@ApiModelProperty("联系人地址")
private String contactsAddress;
@ApiModelProperty("审核状态,0-未申请,1-已申请待审核,2-审核通过,3-审核拒绝")
private String auditStatus;
@ApiModelProperty("租户ID")
private Long tenantId;
}
@ApiModel 和 @ApiModelProperty 是Swagger注解后边会学习。
创建接口实现在shanjupay-merchant-service下新建商户接口实现类:MerchantServiceImpl,并添加新建商户测试方法
本方法从shanjupay_merchant_service数据库的merchant查询数据。
package com.shanjupay.merchant.service;
import com.shanjupay.merchant.api.MerchantService;
import com.shanjupay.merchant.api.dto.MerchantDTO;
import com.shanjupay.merchant.entity.Merchant;
import com.shanjupay.merchant.mapper.MerchantMapper;
import org.springframework.beans.factory.annotation.Autowired;
注意导包.dubbo.config.annotation.Service;
@org.apache.dubbo.config.annotation.Service
public class MerchantServiceImpl implements MerchantService {
@Autowired
MerchantMapper merchantMapper;
@Override
public MerchantDTO queryMerchantById(Long id) {
Merchant merchant = merchantMapper.selectById(id);
MerchantDTO merchantDTO = new MerchantDTO();
merchantDTO.setId(merchant.getId());
merchantDTO.setMerchantName(merchant.getMerchantName());
//设置其他属性....
return merchantDTO;
}
}
应用层
在shanjupay-merchant-application下添加如下pom依赖:
com.shanjupay shanjupay-merchant-api 1.0-SNAPSHOT
在shanjupay-merchant-application下新建商户Controller:MerchantController,并调用商户中心服务提供的新建商户接口
package com.shanjupay.merchant.controller;
import com.shanjupay.merchant.api.MerchantService;
import com.shanjupay.merchant.api.dto.MerchantDTO;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MerchantController {
//注意导入包:import org.apache.dubbo.config.annotation.Reference;
@Reference
private MerchantService merchantService;
+
@GetMapping("/merchants/{id}")
public MerchantDTO queryMerchantById(@PathVariable("id") Long id) {
MerchantDTO merchantDTO = merchantService.queryMerchantById(id);
return merchantDTO;
}
}
1、启动商户平台应用和商户服务
2、访问 .,测试根据id查询商户
如果merchant表没有数据可手动添加后再行测试。如下结果:
Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务(https://swagger.io/)。 它的主要作用是:
- 使得前后端分离开发更加方便,有利于团队协作
- 接口的文档在线自动生成,降低后端开发人员编写接口文档的负担
- 功能测试
Spring已经将Swagger纳入自身的标准,建立了Spring-swagger项目,现在叫Springfox。通过在项目中引入Springfox ,即可非常简单快捷的使用Swagger。
SpringBoot集成Swagger1、在shanjupay-common项目中添加依赖,只需要在shanjupay-common中进行配置即可,因为其他微服务工程都直接或间接依赖shanjupay-common。
io.springfox springfox-swagger2 io.springfox springfox-swagger-ui
2、在shanjupay-merchant-application工程的config包中添加一个Swagger配置类
package com.shanjupay.merchant.config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.Contact;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@ConditionalOnProperty(prefix = "swagger", value = {"enable"}, havingValue = "true")
@EnableSwagger2
public class SwaggerConfiguration {
@Bean
public Docket buildDocket() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(buildApiInfo())
.select()
// 要扫描的API(Controller)基础包
.apis(RequestHandlerSelectors.basePackage("com.shanjupay.merchant.controller"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo buildApiInfo() {
Contact contact = new Contact("开发者", "", "");
return new ApiInfoBuilder()
.title("闪聚支付-商户应用API文档")
.description("")
.contact(contact)
.version("1.0.0").build();
}
}
3、添加SpringMVC配置类:WebMvcConfig,让外部可直接访问Swagger文档[放行]
package com.shanjupay.merchant.config;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Component
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("
@RestController
@Api(value = "商户平台应用接口", tags = "商户平台应用接口", description = "商户平台应用接口")
public class MerchantController {
@org.apache.dubbo.config.annotation.Reference
MerchantService merchantService;
@ApiOperation(value = "根据id查询商户信息")
@GetMapping("/merchants/{id}")
public MerchantDTO queryMerchantById(@PathVariable("id") Long id) {
MerchantDTO merchantDTO = merchantService.queryMerchantById(id);
return merchantDTO;
}
@ApiOperation("测试")
@GetMapping(path = "/hello")
public String hello() {
return "hello";
}
@ApiOperation("测试")
@ApiImplicitParam(name = "name", value = "姓名", required = true, dataType = "string")
@PostMapping(value = "/hi")
public String hi(String name) {
return "hi," + name;
}
}
Swagger测试
1、启动商户应用和商户中心服务,访问:http://localhost:57010/merchant/swagger-ui.html
2、点击其中任意一项即可打开接口详情,如下图所示:
3、点击“Try it out”开始测试,并录入参数信息,然后点击“Execute"发送请求,执行测试返回结果:“hi,李四”
Swagger生成API文档的工作原理:
- shanjupay-merchant-application启动时会扫描到SwaggerConfiguration类
- 在此类中指定了扫描包路径com.shanjupay.merchant.controller,会找到在此包下及子包下标记有 @RestController 注解的controller类
- 根据controller类中的Swagger注解生成API文档
Postman是一款功能强大的http接口测试工具,使用Postman可以完成http各种请求的功能测试。作为服务器端开发人员,当一个业务功能开发完毕后,应该用Postman进行功能测试。
1、请自行在本机安装Postman
2、新建集合(建议一个微服务新建一个对应的集合):闪聚支付-商户应用
3、在闪聚支付-商户应用集合中新建请求,并录入请求信息
填写新建商户接口地址和请求类型后,点击Send发送请求:
小技巧:每个测试都可以进行保存(Ctrl+S),以便于后续使用。



