API相关:
package com.baomidou.mybatisplus.core.toolkit.StringUtils
StringUtils.isNotBlank()不为空
StringUtils.isBlank()为空
import org.springframework.util.StringUtils;
StringUtils.isEmpty:true则为空
swagger、knife4j相关
7.2)swagger
(1)简介
Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务(https://swagger.io/)。 它的主要作用是:
- 使得前后端分离开发更加方便,有利于团队协作
 - 接口的文档在线自动生成,降低后端开发人员编写接口文档的负担
 - 功能测试 Spring已经将Swagger纳入自身的标准,建立了Spring-swagger项目,现在叫Springfox。通过在项目中引入Springfox ,即可非常简单快捷的使用Swagger。
 
(2)SpringBoot集成Swagger
- 引入依赖,在heima-leadnews-model和heima-leadnews-common模块中引入该依赖
io.springfox 
springfox-swagger2 
io.springfox 
springfox-swagger-ui  
只需要在heima-leadnews-common中进行配置即可,因为其他微服务工程都直接或间接依赖即可。
- 在heima-leadnews-common工程中添加一个配置类
 
新增:com.heima.common.swagger.SwaggerConfiguration
package com.heima.common.swagger;
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.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfiguration {
   @Bean
   public Docket buildDocket() {
      return new Docket(DocumentationType.SWAGGER_2)
              .apiInfo(buildApiInfo())
              .select()
              // 要扫描的API(Controller)基础包
              .apis(RequestHandlerSelectors.basePackage(“com.heima”))
              .paths(PathSelectors.any())
              .build();
   }
   private ApiInfo buildApiInfo() {
      Contact contact = new Contact(“黑马程序员”,””,””);
      return new ApiInfoBuilder()
              .title(“黑马头条-平台管理API文档”)
              .description(“黑马头条后台api”)
              .contact(contact)
              .version(“1.0.0”).build();
   }
}
在heima-leadnews-common模块中的resources目录中新增以下目录和文件
文件:resources/META-INF/Spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.heima.common.swagger.SwaggerConfiguration
(3)Swagger常用注解
在Java类中添加Swagger的注解即可生成Swagger接口文档,常用Swagger注解如下:
@Api:修饰整个类,描述Controller的作用 
@ApiOperation:描述一个类的一个方法,或者说一个接口 
@ApiParam:单个参数的描述信息 
@ApiModel:用对象来接收参数 
@ApiModelProperty:用对象接收参数时,描述对象的一个字段 
@ApiResponse:HTTP响应其中1个描述 
@ApiResponses:HTTP响应整体描述 
@ApiIgnore:使用该注解忽略这个API 
@ApiError :发生错误返回的信息 
@ApiImplicitParam:一个请求参数 
@ApiImplicitParams:多个请求参数的描述信息
@ApiImplicitParam属性:
| 属性 | 取值 | 作用 | 
|---|---|---|
| paramType | 查询参数类型 | |
| path | 以地址的形式提交数据 | |
| query | 直接跟参数完成自动映射赋值 | |
| body | 以流的形式提交 仅支持POST | |
| header | 参数在request headers 里边提交 | |
| form | 以form表单的形式提交 仅支持POST | |
| dataType | 参数的数据类型 只作为标志说明,并没有实际验证 | |
| Long | ||
| String | ||
| name | 接收参数名 | |
| value | 接收参数的意义描述 | |
| required | 参数是否必填 | |
| true | 必填 | |
| false | 非必填 | |
| defaultValue | 默认值 | 
我们在ApUserLoginController中添加Swagger注解,代码如下所示:
@RestController
@RequestMapping(“/api/v1/login”)
@Api(value = “app端用户登录”, tags = “ap_user”, description = “app端用户登录API”)
public class ApUserLoginController {
@Autowired<br /> private ApUserService apUserService;@PostMapping("/login_auth")<br /> @ApiOperation("用户登录")<br /> public ResponseResult login(@RequestBody LoginDto dto){<br /> return apUserService.login(dto);<br /> }<br />}<br />LoginDto<br />@Data<br />public class LoginDto {/**<br /> * 手机号<br /> */<br /> @ApiModelProperty(value="手机号",required = true)<br /> private String phone;/**<br /> * 密码<br /> */<br /> @ApiModelProperty(value="密码",required = true)<br /> private String password;<br />}<br />启动user微服务,访问地址:[http://localhost:51801/swagger-ui.html](http://localhost:51801/swagger-ui.html)
7.3)knife4j
(1)简介
knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案,前身是swagger-bootstrap-ui,取名kni4j是希望它能像一把匕首一样小巧,轻量,并且功能强悍!
gitee地址:https://gitee.com/xiaoym/knife4j
官方文档:https://doc.xiaominfo.com/
效果演示:http://knife4j.xiaominfo.com/doc.html
(2)核心功能
该UI增强包主要包括两大核心功能:文档说明 和 在线调试
- 文档说明:根据Swagger的规范说明,详细列出接口文档的说明,包括接口地址、类型、请求示例、请求参数、响应示例、响应参数、响应码等信息,使用swagger-bootstrap-ui能根据该文档说明,对该接口的使用情况一目了然。
 - 在线调试:提供在线接口联调的强大功能,自动解析当前接口参数,同时包含表单验证,调用参数可返回接口响应内容、headers、Curl请求命令实例、响应时间、响应状态码等信息,帮助开发者在线调试,而不必通过其他测试工具测试接口是否正确,简介、强大。
 - 个性化配置:通过个性化ui配置项,可自定义UI的相关显示信息
 - 离线文档:根据标准规范,生成的在线markdown离线文档,开发者可以进行拷贝生成markdown接口文档,通过其他第三方markdown转换工具转换成html或pdf,这样也可以放弃swagger2markdown组件
 - 接口排序:自1.8.5后,ui支持了接口排序功能,例如一个注册功能主要包含了多个步骤,可以根据swagger-bootstrap-ui提供的接口排序规则实现接口的排序,step化接口操作,方便其他开发者进行接口对接
 
(3)快速集成
- 在heima-leadnews-common模块中的pom.xml文件中引入knife4j的依赖,如下:
 
- 创建Swagger配置文件
 
在heima-leadnews-common模块中新建配置类
新建Swagger的配置文件SwaggerConfiguration.java文件,创建springfox提供的Docket分组对象,代码如下:
package com.heima.common.knife4j;
import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
@EnableKnife4j
@Import(BeanValidatorPluginsConfiguration.class)
public class Swagger2Configuration {
@Bean(value = "defaultApi2")<br />    public Docket defaultApi2() {<br />        Docket docket=new Docket(DocumentationType.SWAGGER_2)<br />                .apiInfo(apiInfo())<br />                //分组名称<br />                .groupName("1.0")<br />                .select()<br />                //这里指定Controller扫描包路径<br />                .apis(RequestHandlerSelectors.basePackage("com.heima"))<br />                .paths(PathSelectors.any())<br />                .build();<br />        return docket;<br />    }<br />    private ApiInfo apiInfo() {<br />        return new ApiInfoBuilder()<br />                .title("黑马头条API文档")<br />                .description("黑马头条API文档")<br />                .version("1.0")<br />                .build();<br />    }<br />}<br />以上有两个注解需要特别说明,如下表:
| 注解 | 说明 | 
|---|---|
| @EnableSwagger2 | 该注解是Springfox-swagger框架提供的使用Swagger注解,该注解必须加 | 
| @EnableKnife4j | 该注解是knife4j提供的增强注解,Ui提供了例如动态参数、参数过滤、接口排序等增强功能,如果你想使用这些增强功能就必须加该注解,否则可以不用加 | 
- 添加配置
 
在Spring.factories中新增配置
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.heima.common.swagger.Swagger2Configuration, \
  com.heima.common.swagger.SwaggerConfiguration
- 访问
 
在浏览器输入地址:http://host:port/doc.html
8)网关
(1)在heima-leadnews-gateway导入以下依赖
pom文件
    
        
        
    
    
        
        
    
     
            
            
        
    
        
        
    
(2)在heima-leadnews-gateway下创建heima-leadnews-app-gateway微服务
引导类:
package com.heima.app.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient  //开启注册中心
public class AppGatewayApplication {
public static void main(String[] args) {<br />        SpringApplication.run(AppGatewayApplication.class,args);<br />    }<br />}<br />bootstrap.yml<br />server:<br />  port: 51601<br />spring:<br />  application:<br />    name: leadnews-app-gateway<br />  cloud:<br />    nacos:<br />      discovery:<br />        server-addr: 192.168.200.130:8848<br />      config:<br />        server-addr: 192.168.200.130:8848<br />        file-extension: yml<br />在nacos的配置中心创建dataid为leadnews-app-gateway的yml配置<br />spring:<br />  cloud:<br />    gateway:<br />      globalcors:<br />        add-to-simple-url-handler-mapping: true<br />        corsConfigurations:<br />          '[/**]':<br />            allowedHeaders: "*"<br />            allowedOrigins: "*"<br />            allowedMethods:<br />              - GET<br />              - POST<br />              - DELETE<br />              - PUT<br />              - OPTION<br />      routes:<br />        # 平台管理<br />        - id: user<br />          uri: lb://leadnews-user<br />          predicates:<br />            - Path=/user/**<br />          filters:<br />            - StripPrefix= 1<br />环境搭建完成以后,启动项目网关和用户两个服务,使用postman进行测试<br />请求地址:[http://localhost:51601/user/api/v1/login/login_auth](http://localhost:51601/user/api/v1/login/login_auth)
1.3 全局过滤器实现jwt校验
思路分析:
- 用户进入网关开始登陆,网关过滤器进行判断,如果是登录,则路由到后台管理微服务进行登录
 - 用户登录成功,后台管理微服务签发JWT TOKEN信息返回给用户
 - 用户再次进入网关开始访问,网关过滤器接收用户携带的TOKEN
 - 网关过滤器解析TOKEN ,判断是否有权限,如果有,则放行,如果没有则返回未认证错误
 
具体实现:
第一:
    在认证过滤器中需要用到jwt的解析,所以需要把工具类拷贝一份到网关微服务
第二:
在网关微服务中新建全局过滤器:
package com.heima.app.gateway.filter;
import com.heima.app.gateway.util.AppJwtUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
@Slf4j
public class AuthorizeFilter implements Ordered, GlobalFilter {
    @Override
    public Mono
        //1.获取request和response对象
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
    //2.判断是否是登录<br />        if(request.getURI().getPath().contains("/login")){<br />            //放行<br />            return chain.filter(exchange);<br />        }
    //3.获取token<br />        String token = request.getHeaders().getFirst("token");
    //4.判断token是否存在<br />        if(StringUtils.isBlank(token)){<br />            response.setStatusCode(HttpStatus.UNAUTHORIZED);<br />            return response.setComplete();<br />        }
    //5.判断token是否有效<br />        try {<br />            Claims claimsBody = AppJwtUtil.getClaimsBody(token);<br />            //是否是过期<br />            int result = AppJwtUtil.verifyToken(claimsBody);<br />            if(result == 1 || result  == 2){<br />                response.setStatusCode(HttpStatus.UNAUTHORIZED);<br />                return response.setComplete();<br />            }<br />        }catch (Exception e){<br />            e.printStackTrace();<br />            response.setStatusCode(HttpStatus.UNAUTHORIZED);<br />            return response.setComplete();<br />        }
    //6.放行<br />        return chain.filter(exchange);<br />    }
/**<br />     * 优先级设置  值越小  优先级越高<br />     * @return<br />     */<br />    @Override<br />    public int getOrder() {<br />        return 0;<br />    }<br />}<br />测试:<br />启动user服务,继续访问其他微服务,会提示需要认证才能访问,这个时候需要在heads中设置设置token才能正常访问。
                    