Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

API Routing and Common Pitfalls with Spring Cloud Gateway and Nacos

Tech May 18 3

Dependency management utilizes the following technology stack versions:

<properties>
    <spring-cloud.version>2020.0.1</spring-cloud.version>
    <spring-cloud-alibaba.version>2.2.1.RELEASE</spring-cloud-alibaba.version>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <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>
    </dependencies>
</dependencyManagement>

Gateway Service Configuration

The gateway application requires WebFlux dependencies but not the standard Spring Web MVC starter.

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
</dependencies>

Nacos configuration (gateway-service.properties):

server.port=8080
spring.cloud.gateway.routes[0].id=user-core-route
spring.cloud.gateway.routes[0].uri=lb://user-core-service
spring.cloud.gateway.routes[0].predicates[0]=Path=/api/user/**
spring.cloud.gateway.routes[0].filters[0]=StripPrefix=1

Bootstrap configuration (bootstrap.yml):

spring:
  application:
    name: api-gateway-service
  profiles:
    active: dev
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848
        namespace: dev-namespace-id
        group: DEFAULT_GROUP
        file-extension: properties
        refresh:
          enabled: true
      discovery:
        server-addr: 127.0.0.1:8848

Spring Cloud Gateway operates on Netty. It does not honor the server.servlet.context-path setting, starting only the Netty server via server.port.

Downstream Microservice Setup

The downstream service uses a standard Spring Web MVC setup.

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
</dependencies>

Application properties:

server.port=9090
server.servlet.context-path=/user-svc

Test controller:

@RestController
@RequestMapping("/status")
public class HealthCheckController {

    @GetMapping(value = "/ping")
    public String checkAlive() {
        return "Service is up";
    }
}

Routing resolution: A request to http://localhost:8080/api/user/status/ping is intercepted by the gateway. It strips the first prefix (/api), making the path /user/status/ping. It then resolves user-core-service to 127.0.0.1:9090 and forwards the request to http://127.0.0.1:9090/user-svc/status/ping.

Issue 1: WebFlux vs Spring MVC Dependency Conflict

Introducing a shared utility module into the gateway project caused startup failure with the following error:

Consider defining a bean of type 'org.springframework.http.codec.ServerCodecConfigurer' in your configuration.

This exception occurs because the shared module pulled in spring-boot-starter-web as a transitive dependency. Spring Cloud Gateway is built on Spring WebFlux and Reactor Netty. Including Spring MVC (spring-boot-starter-web) in the classpath disables the WebFlux auto-configuration, leading to the conflict. The resolution is to exclude the web starter from the shared module dependency or remove it entirely from the shared module.

Issue 2: WebSocket SSL Termination on Gateway

When configuring the gateway to handle secure WebSocket connections (WSS) over SSL, a casting exception may occur:

java.lang.ClassCastException: org.apache.catalina.connector.ResponseFacade cannot be cast to reactor.netty.http.server.HttpServerResponse

Despite valid SSL configurations:

server.ssl.key-store=classpath:keystore/tls_cert.p12
server.ssl.key-store-password=secret
server.ssl.key-store-type=PKCS12
server.ssl.enabled=true
server.port=443

This problem stems from the incompatibility between the servlet container and the reactive Netty server used by the gateway, often triggered by accidental MVC dependencies or inherent WebFlux handling of WebSocket upgrades in certain routing scenarios. A reliable workaround involves proxying WSS traffic through a dedicated reverse proxy like Nginx, reserving the gateway strictly for standard HTTPS routing.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.