1、服务发现-Nacos
服务发现、配置管理、服务治理及管理,同类产品还有ZooKeeper、Eureka、Consul
https://nacos.io/zh-cn/docs/what-is-nacos.html
https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md
springboot 服务发现配置
https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/readme-zh.md
- 添加依赖。
? com.alibaba.boot
? nacos-config-spring-boot-starter
? ${latest.version}
注意:版本 0.2.x.RELEASE 对应的是 Spring Boot 2.x 版本,版本 0.1.x.RELEASE 对应的是 Spring Boot 1.x 版本。
2.在 application.properties 中配置 Nacos server 的地址:
nacos.config.server-addr=127.0.0.1:8848
3.在 application.properties 中配置应用名称:
application:
? name: microservicemall-coupon
4.在springboot启动实例类上加上注解@EnableDiscoveryClient
5.启动nacos服务,启动项目,访问
http://localhost:8848/nacos (nacos/nacos)
nacos 配置管理
https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-examples/nacos-example/nacos-config-example/readme-zh.md
1、导入
spring-cloud-starter-alibaba-nacos-config pom
? ? com.alibaba.cloud
? ? spring-cloud-starter-alibaba-nacos-config
2、创建
/src/main/resources/bootstrap.properties文件,配置应用名称和nacos服务器地址
spring.application.name=nacos-config-example
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
3、Conroller 添加@RefreshScope注解,@Value(${配置项})调用
@RefreshScope
class SampleController {
?
@Value("${user.name}")
String userName;
?
@Value("${user.age}")
int age;
}
4、nacos 编辑配置
Data ID 应用名称.properties
bootstrap.properties 多文件配置及解析
#应用名称
spring.application.name=microservicemall-member
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
?
#nacos配置文件的命名空间
spring.cloud.nacos.config.namespace=e4843925-3592-474d-9d08-bd5bb57b5366
#nacos配置文件所在组
spring.cloud.nacos.config.group=member
?
#通过多配置文件与nacos 解雇application.yml,将其分解为一下几个独立的配置文件,这样只需要修改nacos相关的配置 所有的微服务应用都可以得到修改,不必一一去每个服务修改配置文件
#mysql链接配置
spring.cloud.nacos.config.ext-config[0].data-id=mysql.yml
spring.cloud.nacos.config.ext-config[0].group=member
#刷新生效设置
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=member
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=member
spring.cloud.nacos.config.ext-config[2].refresh=true
2、远程调用-feign
https://cloud.spring.io/spring-cloud-static/spring-cloud-openfeign/2.2.2.RELEASE/reference/html/
1、引入maven
? ? ?
? ? ? ? ? org.springframework.cloud
? ? ? ? ? spring-cloud-starter-openfeign
? ? ?
2、编写远程调用接口,通知springcloud这个接口需要调用远程服务
@FeignClient("microservicemall-coupon")
public interface CouponFeignService {
?
? @RequestMapping("coupon/coupon/membercoupons")
? public R list();//与被调用的服务方法一致,粘贴即可
}
3、开启feigin客户端
@EnableFeignClients(basePackages = "com.huaiyu.microservicemall.member.feign")
public class MicroservicemallMemberApplication {
...
4、调用示例
@Autowired
private CouponFeignService couponFeignService;
?
@RequestMapping("coupons")
public R test(){
? MemberEntity memberEntity = new MemberEntity();
? memberEntity.setNickname("张二狗");
? R list = couponFeignService.list();
? return R.ok().put("member",memberEntity).put("coupons",list.get("coupon"));
}
3、网关-gateWay
1、作用
网关的角色是作为一个 API 架构,用来保护、增强和控制对于 API 服务的访问。
API 网关是一个处于应用程序或服务(提供 REST API 接口服务)之前的系统,用来管理授权、访问控制和流量限制等,这样 REST API 接口服务就被 API 网关保护起来,对所有的调用者透明。因此,隐藏在 API 网关后面的业务系统就可以专注于创建和管理服务,而不用去处理这些策略性的基础设施。
2、术语
- Route(路由): 网关的基本模块. 它由ID、目标URI、断言集合和过滤器器集合组成。.如果断言为真,则匹配路由.
- Predicate(断言): 这是一个Java 8函数断言。输入类型是SpringFramework ServerWebExchange。这允许您匹配来自HTTP请求的任何内容,例如请求头或参数。
- Filter: 这些是使用特定工厂构建的SpringFrameworkGatewayFilter的实例。在这里,您可以在发送下游请求之前或之后修改请求和响应。
3、工作原理
客户端向SpringCloudGateway提出请求。如果Gateway Handler映射确定请求与路由匹配,则将其发送到Gateway Web Handler。此处理程序通过特定于请求的筛选链运行请求。过滤器被虚线隔开的原因是过滤器可以在发送代理请求之前和之后运行逻辑。所有“预”过滤逻辑都被执行。然后发出代理请求。在发出代理请求后,将运行“POST”筛选逻辑。
4、路由配置规则
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.2.RELEASE/reference/html/#configuring-route-predicate-factories-and-gateway-filter-factories
4、数据校验-JSR303
maven引用:hibernate-validator不引用jsr303不起作用的
? javax.validation
? validation-api
? 2.0.1.Final
?
? org.hibernate
? hibernate-validator
? 5.1.1.Final
引用javax.validation包
1、配置校验
bean上添加校验注解 如@NotBlank
2、校验生效
action参数上添加@Valid
3、自定义错误数据
参数后紧跟@BindingResult
public R save(@Valid @RequestBody ArticleEntity article, BindingResult result) {
? ?if(result.hasErrors()){
? ? ? ?Map map = new HashMap<>();
? ? ? ?result.getFieldErrors().forEach((item)->{
? ? ? ? ? ?String field = item.getField();
? ? ? ? ? ?String message = item.getDefaultMessage();
? ? ? ? ? ?map.put(field,message);
? ? ? });
? ? ? ?return R.error(400,"提交数据不合法").put("data",map);
? }else{
? articleService.save(article);
? }
? ?return R.ok();
}
4、自定义注解
@Pattern,例如:
@Pattern(regexp="^[a-zA-Z]$",message = "检索首字母必须是一个字母")
扩展:@NotNull、@NotEmpty、@NotBlank区别
@NotNull:不能为null,但可以为empty
@NotEmpty:不能为null,而且长度必须大于0
@NotBlank:只能作用在String上,不能为null,而且调用trim()后,长度必须大于0
5、aop 统一处理校验
@Slf4j
@RestControllerAdvice(value = "com.cuzue.blog.article.controller")
public class ExceptionControllerAdvice {
? ?
? ?@ExceptionHandler(value = MethodArgumentNotValidException.class)
? ?public R handleVaildException(MethodArgumentNotValidException exception){
? ? ? ?log.error(exception.getMessage());
? ? ? ?Map errorMap = new HashMap<>();
? ? ? ?exception.getBindingResult().getFieldErrors().forEach((item)->{
? ? ? ? ? ?String field = item.getField();
? ? ? ? ? ?String message = item.getDefaultMessage();
? ? ? ? ? ?errorMap.put(field,message);
? ? ? });
? ? ? ?return R.error(BizCodeEnum.VAILD_EXCEPTION.getCode(),BizCodeEnum.VAILD_EXCEPTION.getMsg()).put("data",errorMap);
? }
? ?
? ?@ExceptionHandler(value = Exception.class)
? ?public R handleException(Exception exception){
? ? ? ?return R.error(BizCodeEnum.UNKNOW_EXCEPTION.getCode(),BizCodeEnum.UNKNOW_EXCEPTION.getMsg());
? }
?
}
public enum BizCodeEnum {
?
? ?UNKNOW_EXCEPTION(10000,"系统未知异常"),
?
? ?VAILD_EXCEPTION(10001,"参数校验失败");
?
? ?private int code;
? ?private String msg;
?
? ?BizCodeEnum(int code, String msg) {
? ? ? ?this.code = code;
? ? ? ?this.msg = msg;
? }
?
? ?public int getCode() {
? ? ? ?return code;
? }
?
? ?public String getMsg() {
? ? ? ?return msg;
? }
}
6、校验分组
实体类字段添加
@NotBlank(message = "文章名称不能为空",groups = {AddGroup.class,UpdateGroup.class})
controller对应添加
? ?public R update(@Validated(UpdateGroup.class) @RequestBody ArticleEntity article) {
? ? ? ?articleService.updateById(article);
?
? ? ? ?return R.ok();
? }
groups内容为接口类,该接口可以为空,也可以设置分组字段校验排序。
默认没有指定分组的校验注解如@NotBlank,那么在分组校验情况@Validated(UpdateGroup.class)下不生效。
注意在使用@NotBlank等注解时,一定要和@valid一起使用,不然@NotBlank不起作用
5、接口文档生成组件-Swagger
1、maven引用
? ? ?
? ? ?
? ? ? ? ? io.springfox
? ? ? ? ? springfox-swagger2
? ? ? ? ? 2.9.2
? ? ?
? ? ?
? ? ? ? ? io.springfox
? ? ? ? ? springfox-swagger-ui
? ? ? ? ? 2.9.2
? ? ?
? ? ? ?
? ? ? ? ? org.springframework.boot
? ? ? ? ? spring-boot-starter-web
? ? ?
2、配置Swagger
@Configuration
@EnableSwagger2
public class SwaggerConfig {
? ?@Bean
? ?public Docket createRestApi() {
? ? ? ?return new Docket(DocumentationType.SWAGGER_2)
? ? ? ? ? ? ? .pathMapping("/")
? ? ? ? ? ? ? .select()
? ? ? ? ? ? ? .apis(RequestHandlerSelectors.basePackage("com.cuzue.blog.article.controller"))
? ? ? ? ? ? ? .paths(PathSelectors.any())
? ? ? ? ? ? ? .build().apiInfo(new ApiInfoBuilder()
? ? ? ? ? ? ? ? ? ? ? .title("文章服务")
? ? ? ? ? ? ? ? ? ? ? .description("博客正文、分类栏目")
? ? ? ? ? ? ? ? ? ? ? .version("1.0")
? ? ? ? ? ? ? ? ? ? ? .contact(new Contact("张怀宇","www.cuzue.com","991446772@qq.com"))
? ? ? ? ? ? ? ? ? ? ? .license("The Apache License")
? ? ? ? ? ? ? ? ? ? ? .licenseUrl("http://www.cuzue.com")
? ? ? ? ? ? ? ? ? ? ? .build());
? }
}
3、controller注释
@RequestMapping(value = "/update",method = RequestMethod.POST)
? ?@ApiOperation("更新文章")
? ?@ApiImplicitParams({
? ? ? ? ? ?@ApiImplicitParam(name = "ArticleEntity", value = "文章实体",required = true),
? }
? )
? ?public R update(@Valid @Validated(UpdateGroup.class) @RequestBody ArticleEntity article) {
? ? ? ?articleService.updateById(article);
?
? ? ? ?return R.ok();
? }
4、访问
ip:端口/swagger-ui.html