return chain.filter(exchange).then(Mono.fromRunnable(()->{
           ServerHttpResponse response = exchange.getResponse();
           HttpStatus responseStatus = response.getStatusCode();

           if(responseStatus.equals(HttpStatus.FOUND)){
//                String newResponseBody =
//                        "<body>\n" +
//                                "      <h1 style=\"color:red;text-align:center\">Bad Request </h1>\n" +
//                                "      <p>If you are seeing this page it means response body is modified.</p>\n" +
//                                "  </body>";
//                response.setStatusCode(HttpStatus.OK);
//                response.getHeaders().setContentLength(newResponseBody.length());
//                DataBuffer dataBuffer = response.bufferFactory().wrap(newResponseBody.getBytes(StandardCharsets.UTF_8));
//                response.writeWith(Mono.just(dataBuffer)).subscribe();
//                exchange.mutate().response(response).build();
               if(response.getHeaders().containsKey("Location")){
                   URI uri = exchange.getRequest().getURI();
                   String path = uri.getPath();
                   String[] pathSegments = path.split("/");
                   if(pathSegments.length>2){
                       String extractedPath = "/" + pathSegments[1] + "/" + pathSegments[2];
                       List<String> location = response.getHeaders().get("Location");
                       response.getHeaders().setLocation(URI.create(extractedPath+location.get(0)));
                   }

               }


//                return response.writeWith(Mono.empty());
           }
       }));
   }

https://docs.spring.io/spring-cloud-gateway/reference/spring-cloud-gateway/gatewayfilter-factories/redirectto-factory.html

Spring Cloud Gateway || Modify Response Body Using Post Global Filter

@Configuration
public class DynamicRewriteRoute {
//    @Value("${rewrite.backend.uri}")
    private String backendUri="http://192.168.10.30:3000";
    private static Random rnd = new Random();
    @Bean
    public RouteLocator dynamicZipCodeRoute(RouteLocatorBuilder builder) {
        System.out.println("11111111111111");
        return builder.routes()
                .route("dynamicRewrite", r ->
                        r.path("/proxy2/8080/**")
                                .filters(f -> f.filter((exchange, chain) -> {
                                    ServerHttpRequest req = exchange.getRequest();
                                    addOriginalRequestUrl(exchange, req.getURI());
                                    String path = req.getURI().getRawPath();
//                                    String newPath = path.replaceAll(
//                                            "/proxy2/8080/(?<zipcode>.*)",
//                                            "/${zipcode}-" + String.format("%03d", rnd.nextInt(1000)));
                                    String newPath = path.replaceAll(
                                            "/proxy2/8080/(?<segment>.*)", "/${segment}" );

                                    backendUri = backendUri.replace("3000","8080");
                                    ServerHttpRequest request = req.mutate().path(newPath).build();
                                    exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, request.getURI());
                                    return chain.filter(exchange.mutate().request(request).build());
                                }))
                                .uri(backendUri))
                .build();

    }

}
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
  labels:
    app: test-pod
spec:
  # 定义容器,可以多个
  containers:
    - name: test-k8s # 容器名字
      image: registry.cn-hangzhou.aliyuncs.com/wybioinfo/code-server:latest # 镜像
      volumeMounts:
        - {name: vol-1, mountPath: /data}
  volumes:
  - name: vol-1
    persistentVolumeClaim: {claimName: nextflowdata}

---

apiVersion: v1
kind: Service
metadata:
  name: test-pod
spec:
  selector:
    app: test-pod
  # 默认 ClusterIP 集群内可访问,NodePort 节点可访问,LoadBalancer 负载均衡模式(需要负载均衡器才可用)
  type: NodePort
  ports:
    - port: 8443        # 本 Service 的端口
      targetPort: 8443  # 容器端口
      nodePort: 31000   # 节点端口,范围固定 30000 ~ 32767

  #  kubectl port-forward  --address 0.0.0.0 svc/test-pod 31000:8443 

# docker run -it --name code-server -p 8080:8080    codercom/code-server:latest
# docker run -it --init -p 3000:3000 -v "$(pwd):/home/workspace:cached" gitpod/openvscode-server
server:
  port: 30000
spring:
  cloud:
    gateway:
      globalcors:
        corsConfigurations:
          '[/**]':
              allowedOrigins: "*"
              allowedMethods: "*"
              allowedHeaders: "*"
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      filter:
        remove-non-proxy-headers:
          headers:
          - Proxy-Authenticate
          - Proxy-Authorization
          - TE
          - Trailer
          - Transfer-Encoding
      httpclient:
        websocket:
          max-frame-payload-length: 3000000 
      routes:
        - id:  docker-app
          uri: http://192.168.3.60:82
          predicates:
            - Path=/app/**
        - id: vscode-cloud
          uri: http://192.168.3.60:40001
          predicates:
            - Path=/vscode/**
          filters:
            - RewritePath=/vscode/(?<segment>.*), /$\{segment}

  redis:
    host: 127.0.0.1
    port: 6379
    password:
    timeout: 5000
    jedis:
      pool:
        max-active: 3
        max-idle: 3
        min-idle: 1
        max-wait: -1
server {
    listen 82;
    charset utf-8;
     client_max_body_size 200m;

    large_client_header_buffers 4 16k;
    #root /ssd1/shanjun/applications/web/;
    location /app/ {
        if ($request_uri ~ /app/(.+)){
            set $rightUrl $1;
        }
        add_header X-debug-message "A static file was served" always;
        proxy_pass http://192.168.3.60:$rightUrl;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        add_header bbb "$rightUrl";
        proxy_set_header Origin "";
        rewrite ^/app/$rightUrl(.*)$ /$1 break;
            # First attempt to serve request as file, then
            # as directory, then fall back to displaying a 404.
            #try_files $uri $uri/ =404;
            #proxy_pass http://10.110.1.12:8080;
    }

    location /node/ {
        proxy_pass http://192.168.3.60:40001;
        rewrite ^/node/(.*)$ /$1 break;
                    proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "Upgrade";
        proxy_set_header Origin "";
    }
}
server:
  port: 30000
spring:
  cloud:
    gateway:
      filter:
        remove-hop-by-hop:
          headers:
      httpclient:
        websocket:
          max-frame-payload-length: 3000000 
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:

        - id:  vscode-cloud
          uri: http://192.168.10.30:8080
          predicates:
            - Path=/proxy/**
          filters:
            - RewritePath=/proxy/(?<segment>.*), /$\{segment}

  redis:
    host: 192.168.10.177
    port: 6381
    password: 123456
    timeout: 5000
    jedis:
      pool:
        max-active: 3
        max-idle: 3
        min-idle: 1
        max-wait: -1

http://xxx:30000/app/40001/?folder=/home/coder

https://www.baeldung.com/spring-cloud-gateway-url-rewriting
https://docs.spring.io/spring-cloud-gateway/docs/2.2.7.RELEASE/reference/html/#removehopbyhop-headers-filter