开源框架-SpringCloud系列Spring Cloud

spring cloud Gateway 学习

2020-04-13  本文已影响0人  _大叔_

学习第一步先看官网介绍,了解个大概也行啊 官网地址

一、起飞

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
    </dependencies>

注意spring boot 和 spring cloud 版本必须一致,否则会有如下报错:

java.lang.NoSuchMethodError: reactor.netty.http.client.HttpClient.chunkedTransfer(Z)Lreactor/netty/http/client/HttpClient;

版本对应查看这里 https://github.com/spring-projects/spring-cloud/wiki

二、配置文件

spring:
  application:
    name: gateway

  cloud:
    gateway:
      routes: #路由
          # 当前路由转发的标识,默认式uuid,一般自定义
        - id: user_router
          # 请求最终转发的地址
          uri: http://localhost:8900
          # 路由的优先级,数字越小优先级越高
          order: 1
          # 断言(条件判断,返回值为boolean,代表转发请求要满足的条件)
          predicates:
            # 当请求路径满足Path指定的规则,才会转发
            - Path=/user-server/**
          # 过滤器 请求传递过程中,对请求进行做一些手脚
          filters:
            # 在请求转发之前 去掉 predicates 里的 Path 指定路径 如 /user/** 去掉 /user
            - StripPrefix=1

predicates 规则有很多种,我现在这种式根据路径匹配,比如如下,是根据时间段来限定请求

spring:
  cloud:
    gateway:
      routes:
      - id: between_route
        uri: https://example.org
        predicates:
        - Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]

而 filter 也很简单了,也就是在请求的时候我们可以添加一些东西,或者去掉一些东西,而我写的 - StripPrefix=1 意思就是把 predicates 匹配的 user-server 在转发前去掉,否则我们正常请求是 localhost:8080/user/addUser,实际就变成 localhost:8080/user-server/user/addUser 这样就会404.

三、全局 filter 实现

@Configuration
public class CustomizeGlobalFilter {

    @Resource
    private NacosDiscoveryProperties nacosDiscoveryProperties;

    @Bean
    public NacosNamingService nacosNamingService() {
        return new NacosNamingService(nacosDiscoveryProperties.getServerAddr());
    }

    @Bean
    public GlobalFilter tokenFilter() {
        return new TokenFilter();
    }

}
@Slf4j
public class TokenFilter implements GlobalFilter, Ordered {

    @Resource
    NacosNamingService nacosNamingService;

    @Override
    @SuppressWarnings("Duplicates")
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.debug("test");
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return -1;
    }

}

四、全局异常

import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.ResourceProperties;
import org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler;
import org.springframework.boot.web.reactive.error.ErrorAttributes;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.web.reactive.function.server.*;

import java.util.HashMap;
import java.util.Map;

/**
 * @author big uncle
 * @date 2020/12/14 15:09
 * @module
 **/
public class CustomizeErrorHandler extends DefaultErrorWebExceptionHandler {

    public CustomizeErrorHandler(ErrorAttributes errorAttributes, ResourceProperties resourceProperties, ErrorProperties errorProperties, ApplicationContext applicationContext) {
        super(errorAttributes, resourceProperties, errorProperties, applicationContext);
    }

    @Override
    protected Map<String, Object> getErrorAttributes(ServerRequest request, boolean includeStackTrace) {
        // 这里其实可以根据异常类型进行定制化逻辑
        Throwable error = super.getError(request);
        Map<String, Object> errorAttributes = new HashMap<>(3);
        errorAttributes.put("code", HttpStatus.INTERNAL_SERVER_ERROR.value());
        errorAttributes.put("msg", "path = "+ request.path() +"; method = "+request.methodName()+ "; msg = " + error.getMessage());
        errorAttributes.put("data", "");
        return errorAttributes;
    }

    @Override
    protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
        return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
    }

    @Override
    protected int getHttpStatus(Map<String, Object> errorAttributes) {
        return (Integer)errorAttributes.get("code");
    }


}

import com.giant.cloud.error.CustomizeErrorHandler;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.web.ResourceProperties;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.reactive.error.ErrorAttributes;
import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.web.reactive.result.view.ViewResolver;

import java.util.Collections;
import java.util.List;

/**
 * @author big uncle
 * @date 2020/12/14 15:25
 * @module
 **/
@Configuration
@EnableConfigurationProperties({ServerProperties.class, ResourceProperties.class})
public class ErrorConfig {

    private final ServerProperties serverProperties;

    private final ApplicationContext applicationContext;

    private final ResourceProperties resourceProperties;

    private final List<ViewResolver> viewResolvers;

    private final ServerCodecConfigurer serverCodecConfigurer;

    public ErrorConfig(ServerProperties serverProperties,
                                     ResourceProperties resourceProperties,
                                     ObjectProvider<List<ViewResolver>> viewResolversProvider,
                                     ServerCodecConfigurer serverCodecConfigurer,
                                     ApplicationContext applicationContext) {
        this.serverProperties = serverProperties;
        this.applicationContext = applicationContext;
        this.resourceProperties = resourceProperties;
        this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
        this.serverCodecConfigurer = serverCodecConfigurer;
    }

    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public ErrorWebExceptionHandler errorWebExceptionHandler(ErrorAttributes errorAttributes) {
        CustomizeErrorHandler exceptionHandler = new CustomizeErrorHandler(
                errorAttributes,
                this.resourceProperties,
                this.serverProperties.getError(),
                this.applicationContext);
        exceptionHandler.setViewResolvers(this.viewResolvers);
        exceptionHandler.setMessageWriters(this.serverCodecConfigurer.getWriters());
        exceptionHandler.setMessageReaders(this.serverCodecConfigurer.getReaders());
        return exceptionHandler;
    }


}

上一篇下一篇

猜你喜欢

热点阅读