Spring-Cloud-Alibaba

篇幅有限

完整内容及源码关注公众号:ReverseCode,发送

SpringCloudAlibaba

Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。

依托 Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里微服务解决方案,通过阿里中间件来迅速搭建分布式应用系统。

  • Sentinel:把流量作为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
  • Nacos:一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
  • RocketMQ:一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务。
  • Dubbo:Apache Dubbo™ 是一款高性能 Java RPC 框架。
  • Seata:阿里巴巴开源产品,一个易于使用的高性能微服务分布式事务解决方案。
  • Alibaba Cloud ACM:一款在分布式架构环境中对应用配置进行集中管理和推送的应用配置中心产品。
  • Alibaba Cloud OSS: 阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务。您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。
  • Alibaba Cloud SchedulerX: 阿里中间件团队开发的一款分布式任务调度产品,提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。
  • Alibaba Cloud SMS: 覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。

虚拟机

安装virtualbox 6

vagrant安装好后进入镜像仓库搜索需要安装的镜像

mkdir centos7 && vagrant init centos/7 && vagrant up && vagrant ssh 创建并开启镜像,修改网络桥接

如果太慢,进入centos/7仓库下载,手动加载vagrant box add centos/7 CentOS-7-x86_64-Vagrant-2004_01.VirtualBox.box

vim Vagrantfile 修改配置并重启vagrant reload,保存虚拟机与主机可ping通,sudo passwd root 设置root权限

1
2
# config.vm.network "private_network", ip: "192.168.56.10"  host-only
config.vm.network "public_network" 桥接

安装nodejs并配置淘宝源npm config set registry http://registry.npm.taobao.org/

安装docker

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
sudo yum install -y yum-utils
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install -y docker-ce docker-ce-cli containerd.io
yum list docker-ce --showduplicates | sort -r
sudo systemctl start docker
sudo docker images
sudo systemctl enable docker

镜像加速器

1
2
3
4
5
6
7
8
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://3gki6pei.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

mysql

1
2
3
4
5
6
7
8
9
10
docker run -p 3306:3306 --name mysql \
-v /mydata/mysql/log:/var/log/mysal \
-v /mydata/mysql/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7
docker exec -it mysql /bin/bash
mysql -uroot -proot
use mysql;
alter user 'root'@'%' identified with mysql_native_password by 'root';
flush privileges;

vi /mydata/mysql/conf/my.cnf 修改编码配置

1
2
3
4
5
6
7
8
9
10
11
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
skip-name-resolve

docker restart mysql && cat /etc/mysql/my.cnf && docker update mysql –restart=always

redis

vi /mydata/redis/conf/redis.conf 配置appendonly yes持久化硬盘

1
2
3
4
5
docker run -p 6379:6379 --name redis -v /mydata/redis/data:/data \
-v /mydata/redis/conf/redis.conf:/etc/redis/redis.conf \
-d redis:3.2 redis-server /etc/redis/redis.conf --appendonly yes
docker exec -it redis redis-cli
docker update redis --restart=always

maven

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>*</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
<profile>
<id>jdk18</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>

idea安装lombok,mybatisX插件

vscode安装Auto Close Tag,Auto Rename Tag,Chinese,Eslint,HTML CSS Support,HTML Snippets,JavaScript(ES6),Live Server,open in browser,Vetur,Vue 2 Snippets插件

git配置

1
2
3
4
5
git config --global user.name "username" //(名字) # 配置邮箱
git config --global user.email "username@email.com" //(注册账号时用的邮箱)
ssh-keygen -t rsa -C "xxxxx@xxxxx.com" 进入git bash生成公私钥
cat ~/.ssh/id_rsa.pub
ssh -T git@gitee.com 测试是否成功即可

Nacos注册中心

新建Spring Initializr作为provider项目jdk1.8并导入Web中的Spring Web和Spring Cloud Routing的OpenFeign组件,设置-Xmx100m 启动Application使用最大内存

启动nacos-server-1.3.1.zip访问nacos

修改依赖如下

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
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR3</spring-cloud.version>
<spring-cloud-alibaba.version>2.1.0.RELEASE</spring-cloud-alibaba.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<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>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

添加application.yml配置

1
2
3
4
5
6
7
8
9
spring:
application:
name: provider
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
server:
port: 8000

ProviderApplication启动类添加@EnableDiscoveryClient,启动后在nacos控制台查看已经上线的服务

Nacos配置中心

默认配置读取

application.properties添加配置

1
2
user.name=onejane
user.age=20

Controller实现读取

1
2
3
4
5
6
7
8
9
10
11
12
@RestController
@RequestMapping("test")
public class UserController {
@Value("${user.name}")
private String name;
@Value("${user.age}")
private Integer age;
@RequestMapping("/user")
public void test(){
System.out.println(name+":"+age);
}
}

Nacos配置

项目添加config依赖

1
2
3
4
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

Provider项目创建bootstrap.properties

1
2
spring.application.name=provider
spring.cloud.nacos.config.server-addr=127.0.0.1:8848

Nacos中配置provider.properties,默认规则,取public命名空间的应用名.properties,类型为Properties,相同与application.properties时优先使用配置中心的配置。

1
2
user.name=onejane1
user.age=23

多环境配置

配置命名空间provider,命名空间ID为f7d49148-09a8-4ca1-8a40-c52e9cb627b5,在该命名空间下配置provider.properties,Group为prod

1
2
user.name=onejane2
user.age=23

配置bootstrap.properties

1
2
3
4
spring.application.name=provider
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.namespace=f7d49148-09a8-4ca1-8a40-c52e9cb627b5
spring.cloud.nacos.config.group=prod

命名空间,用于配置隔离,默认新增的所有配置都在public空间。

1、开发,测试,生产:利用命名空间来做环境隔离。在bootstrap.properties;配置spring.cloud.nacos.config.namespace需要使用哪个命名空间下的配置

2、每一个微服务之间互相隔离配置,每一个微服务都创建自己的命名空间,只加载自己命名空间下的所有配置

每个微服务创建自己的命名空间,使用配置分组区分环境,dev,test,prod

多文件配置

在Nacos中provider微服务命名空间配置datasource.yml

1
2
3
4
5
6
spring:
datasource:
username: root
password: root
url: jdbc:mysql://172.20.1.185:3306/user
driver-class-name: com.mysql.jdbc.Driver

配置mybatis.yml

1
2
3
4
5
mybatis-plus:
mapper-locations: classpath:/mapper/**/*.xml
global-config:
db-config:
id-type: auto

配置service.yml

1
2
3
4
5
6
7
8
9
spring:
application:
name: provider
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
server:
port: 7000

注释application.yml中所有配置并在bootstrap.properties中实现多文件配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
spring.application.name=provider

spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.namespace=f7d49148-09a8-4ca1-8a40-c52e9cb627b5
spring.cloud.nacos.config.group=prod

spring.cloud.nacos.config.ext-config[0].data-id=datasource.yml
spring.cloud.nacos.config.ext-config[0].group=dev
spring.cloud.nacos.config.ext-config[0].refresh=true

spring.cloud.nacos.config.ext-config[1].data-id=mybatis.yml
spring.cloud.nacos.config.ext-config[1].group=dev
spring.cloud.nacos.config.ext-config[1].refresh=true

spring.cloud.nacos.config.ext-config[2].data-id=other.yml
spring.cloud.nacos.config.ext-config[2].group=dev
spring.cloud.nacos.config.ext-config[2].refresh=true

Mybatis-Plus持久化

引入依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.17</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
</dependency>

配置数据源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
spring:
datasource:
username: root
password: root
url: jdbc:mysql://172.20.1.185:3306/user
driver-class-name: com.mysql.jdbc.Driver
jackson:
date-format: yyyy-MM-dd HH:mm:ss # 输出日期自动转换
mybatis-plus:
mapper-locations: classpath:/mapper/**/*.xml
global-config:
db-config:
id-type: auto
logic-delete-value: 1 # 逻辑删除
logic-not-delete-value: 0

配置扫描包

1
@MapperScan("com.onejane.demo.provider.dao")

添加实体类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Data
@TableName("user_info")
public class UserInfoEntity implements Serializable {
private static final long serialVersionUID = 1L;

@TableId
private Long id;
private String name;
private Long age;
/**
* 是否显示[0-不显示,1显示] 用于逻辑删除
*/
@TableLogic(value = "1",delval = "0")
private Integer status;
}

逻辑删除实现

1
2
3
4
5
6
7
@Autowired
UserInfoSerivce userInfoSerivce;
@RequestMapping("/delete")
public R delete(Long[] ids){
userInfoSerivce.removeByIds(Arrays.asList(ids));
return R.ok();
}

分页查询实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public interface UserInfoSerivce extends IService<UserInfoEntity> {
PageUtils queryPage(Map<String, Object> params);
}
@Service("userInfoService")
public class UserInfoServiceImpl extends ServiceImpl<UserInfoDao, UserInfoEntity> implements UserInfoSerivce {
@Override
public PageUtils queryPage(Map<String, Object> params) {
IPage<UserInfoEntity> page = this.page(
new Query<UserInfoEntity>().getPage(params),
new QueryWrapper<UserInfoEntity>()
);

return new PageUtils(page);
}
}
@RequestMapping("/list")
public R list(@RequestParam Map<String, Object> params){
PageUtils page = userInfoSerivce.queryPage(params);
return R.ok().put("page", page);
}

分页配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Configuration
@EnableTransactionManagement //开启事务
@MapperScan("com.onejane.demo.provider.dao")
public class MyBatisConfig {

//引入分页插件
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
paginationInterceptor.setOverflow(true);
// 设置最大单页限制数量,默认 500 条,-1 不受限制
paginationInterceptor.setLimit(1000);
return paginationInterceptor;
}
}

Feign远程调用

新建Spring Initializr作为consumer项目jdk1.8并导入Web中的Spring Web和Spring Cloud Routing的OpenFeign组件,设置-Xmx100m 启动Application使用最大内存

provider提供api,启动类配置@EnableDiscoveryClient后启动应用

consumer中引入nacos依赖

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
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR3</spring-cloud.version>
<spring-cloud-alibaba.version>2.1.0.RELEASE</spring-cloud-alibaba.version>
</properties>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependencyManagement>
<dependencies>
<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>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

Member作为consumer获取feign调用,定义feign方法

1
2
3
4
5
6
7
@FeignClient("provider")
public interface ProviderFeignService {

@RequestMapping("/test/list")
public void test();

}

consumer在控制器中申请远程调用,并在启动类中开启feign调用@EnableFeignClients(basePackages = "com.onejane.demo.consumer.feign")并将consumer加入nacos注册中心@EnableDiscoveryClient

1
2
3
4
5
@FeignClient("provider")
public interface ProviderFeignService {
@RequestMapping("/test/user")
public void test();
}

在application.yml中配置nacos

1
2
3
4
5
6
7
8
9
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
application:
name: consumer
server:
port: 7000

开启feign远程调用

1
2
3
4
5
6
7
8
9
10
@RestController
@RequestMapping("test")
public class UserInfoController {
@Autowired
ProviderFeignService providerFeignService;
@RequestMapping("/user")
public void test(){
providerFeignService.test();
}
}

Gateway网关

修改provider项目新增server.servlet.context-path: /provider

新建Spring Initializr作为网关项目项目jdk1.8并导入Spring Cloud Routing的Gateway组件

pom依赖修改

1
2
3
4
5
6
7
8
9
10
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR3</spring-cloud.version>
</properties>

application.properties添加配置

1
2
3
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
spring.application.name=gateway
server.port=88

在nacos中配置微服务命名空间gateway,ID为7601cb5a-a9dd-43d8-a1b9-a37952674df2,添加配置文件gateway.yml

1
2
3
spring:
application:
name: gateway

bootstrap.properties配置命名空间

1
2
3
spring.application.name=gateway
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.namespace=7601cb5a-a9dd-43d8-a1b9-a37952674df2

application.yml中添加网关配置,访问http://localhost:88/?url=qq 则跳转到https://www.qq.com?url=qq, 访问http://localhost:88/?url=baidu 则跳转到https://www.baidu.com?url=baidu

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
spring:
cloud:
gateway:
routes:
- id: test_route
uri: https://www.baidu.com
predicates:
- Query=url,baidu

- id: qq_route
uri: https://www.qq.com
predicates:
- Query=url,qq
- id: provider_route
uri: lb://provider
predicates:
- Path=/api/provider/**
filters:
- RewritePath=/api/(?<segment>.*),/$\{segment}
application:
name: gateway


# http://localhost:88/api/provider/test/user ==> http://localhost:8000/provider/test/user

在启动类中配置@EnableDiscoveryClient,并过滤掉数据库配置@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})

跨域

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Configuration
public class GulimallCorsConfiguration {

@Bean
public CorsWebFilter corsWebFilter(){
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();

CorsConfiguration corsConfiguration = new CorsConfiguration();

//1、配置跨域
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.setAllowCredentials(true);

source.registerCorsConfiguration("/**",corsConfiguration);
return new CorsWebFilter(source);
}
}

阿里云oss

引入阿里云oss依赖

1
2
3
4
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alicloud-oss</artifactId>
</dependency>

application.yml配置阿里云AccessKey

1
2
3
4
5
6
7
8
spring:
cloud:
alicloud:
access-key: ***
secret-key: ***
oss:
endpoint: oss-cn-beijing.aliyuncs.com
bucket: onejane-opencv

上传图片一般先通过服务端签名后前端直传

阿里云oss

JSR303

通过自定义校验,分组校验及全局校验实现对Spring MVC入参的参数校验。

加入validation依赖

1
2
3
4
5
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>

加入校验注解

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
/**
* 品牌id
*/
@NotNull(message = "修改必须指定品牌id",groups = {UpdateGroup.class})
@Null(message = "新增不能指定id",groups = {AddGroup.class})
@TableId
private Long brandId;
/**
* 品牌名
*/
@NotBlank(message = "品牌名必须提交",groups = {AddGroup.class,UpdateGroup.class})
private String name;
/**
* 品牌logo地址
*/
@NotBlank(groups = {AddGroup.class})
@URL(message = "logo必须是一个合法的url地址",groups={AddGroup.class,UpdateGroup.class})
private String logo;
/**
* 介绍
*/
private String descript;
/**
* 显示状态[0-不显示;1-显示]
*/
@NotNull(groups = {AddGroup.class, UpdateStatusGroup.class})
@ListValue(vals={0,1},groups = {AddGroup.class, UpdateStatusGroup.class})
private Integer showStatus;
/**
* 检索首字母
*/
@NotEmpty(groups={AddGroup.class})
@Pattern(regexp="^[a-zA-Z]$",message = "检索首字母必须是一个字母",groups={AddGroup.class, UpdateGroup.class})
private String firstLetter;
/**
* 排序
*/
@NotNull(groups={AddGroup.class})
@Min(value = 0,message = "排序必须大于等于0",groups={AddGroup.class,UpdateGroup.class})
private Integer sort;

建立分组校验类

1
2
3
public interface AddGroup {}
public interface UpdateGroup {}
public interface UpdateStatusGroup {}

自定义异常注解

1
2
3
4
5
6
7
8
9
10
11
12
13
@Documented
@Constraint(validatedBy = { ListValueConstraintValidator.class })
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
public @interface ListValue {
String message() default "{com.onejane.demo.provider.valid.ListValue.message}";

Class<?>[] groups() default { };

Class<? extends Payload>[] payload() default { };

int[] vals() default { };
}

自定义异常实现

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
public class ListValueConstraintValidator implements ConstraintValidator<ListValue,Integer> {

private Set<Integer> set = new HashSet<>();
//初始化方法
@Override
public void initialize(ListValue constraintAnnotation) {

int[] vals = constraintAnnotation.vals();
for (int val : vals) {
set.add(val);
}

}

//判断是否校验成功

/**
*
* @param value 需要校验的值
* @param context
* @return
*/
@Override
public boolean isValid(Integer value, ConstraintValidatorContext context) {

return set.contains(value);
}
}

控制器层加入字段校验配置

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
@RequestMapping("/save")
public R save(@Validated({AddGroup.class}) @RequestBody BrandEntity brand/*,BindingResult result*/){
// if(result.hasErrors()){
// Map<String,String> map = new HashMap<>();
// //1、获取校验的错误结果
// result.getFieldErrors().forEach((item)->{
// //FieldError 获取到错误提示
// String message = item.getDefaultMessage();
// //获取错误的属性的名字
// String field = item.getField();
// map.put(field,message);
// });
//
// return R.error(400,"提交的数据不合法").put("data",map);
// }else {
// 为避免每次请求都判断异常输出,通过ExceptionControllerAdvice实现全局异常控制
brandService.save(brand);

return R.ok();
}
/**
* 修改
*/
@RequestMapping("/update")
public R update(@Validated(UpdateGroup.class) @RequestBody BrandEntity brand){
brandService.updateById(brand);
return R.ok();
}

/**
* 修改状态
*/
@RequestMapping("/update/status")
public R updateStatus(@Validated(UpdateStatusGroup.class) @RequestBody BrandEntity brand){
brandService.updateById(brand);
return R.ok();
}

全局异常控制配置

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
@Slf4j
//@ResponseBody
//@ControllerAdvice(basePackages = "com.onejane.demo.provider.controller")
@RestControllerAdvice(basePackages = "com.onejane.demo.provider.controller")
public class ExceptionControllerAdvice {


@ExceptionHandler(value= MethodArgumentNotValidException.class)
public R handleVaildException(MethodArgumentNotValidException e){
log.error("数据校验出现问题{},异常类型:{}",e.getMessage(),e.getClass());
BindingResult bindingResult = e.getBindingResult();

Map<String,String> errorMap = new HashMap<>();
bindingResult.getFieldErrors().forEach((fieldError)->{
errorMap.put(fieldError.getField(),fieldError.getDefaultMessage());
});
return R.error(BizCodeEnume.VAILD_EXCEPTION.getCode(),BizCodeEnume.VAILD_EXCEPTION.getMsg()).put("data",errorMap);
}

@ExceptionHandler(value = Throwable.class)
public R handleException(Throwable throwable){

log.error("错误:",throwable);
return R.error(BizCodeEnume.UNKNOW_EXCEPTION.getCode(),BizCodeEnume.UNKNOW_EXCEPTION.getMsg());
}

}
文章作者: J
文章链接: http://onejane.github.io/2021/03/11/Spring-Cloud-Alibaba/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 万物皆可逆向
支付宝打赏
微信打赏