You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring响应式栈(Netty)中如何便捷获取请求URI及相关属性?

响应式栈(Netty)中便捷获取请求URI属性的方案

方案1:借助ServerWebExchangeContext直接获取上下文请求

在Spring WebFlux的响应式环境中,可通过ServerWebExchangeContext在请求上下文范围内的任意组件中直接获取当前请求的ServerWebExchange,进而提取URI属性:

  • 仅能在Web请求的处理上下文(如控制器方法、过滤器、被请求上下文调用的Bean)中使用
  • 代码示例:
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.ServerWebExchangeContext;

// 在需要提取属性的代码段中调用
ServerWebExchange exchange = ServerWebExchangeContext.current();
URI uri = exchange.getRequest().getURI();

// 提取目标属性
String scheme = uri.getScheme();
String schemeSpecificPart = uri.getSchemeSpecificPart();
String host = uri.getHost();
int port = uri.getPort();

注意:该方式依赖请求上下文的绑定,非请求线程中调用会抛出异常。

方案2:通过过滤器封装属性到Reactor Context

如果需要在异步操作或下游组件中传递URI属性,可自定义过滤器将属性存入Reactor的Context,实现全请求链路的可访问性:

  1. 编写自定义过滤器:
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

public class UriContextFilter implements WebFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        URI uri = request.getURI();
        
        // 将URI属性写入Reactor Context
        return chain.filter(exchange)
                .contextWrite(ctx -> ctx
                        .put("uri.scheme", uri.getScheme())
                        .put("uri.schemeSpecificPart", uri.getSchemeSpecificPart())
                        .put("uri.host", uri.getHost())
                        .put("uri.port", uri.getPort()));
    }
}
  1. 注册过滤器到Spring容器:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class WebConfig {
    @Bean
    public UriContextFilter uriContextFilter() {
        return new UriContextFilter();
    }
}
  1. 在业务逻辑中从Context提取属性:
import reactor.core.publisher.Mono;

public Mono<String> getHostFromContext() {
    return Mono.deferContextual(ctxView -> {
        String host = ctxView.get("uri.host");
        return Mono.just(host);
    });
}

方案3:针对特定属性的简化提取

部分属性可通过请求头或请求状态直接推断,无需完整获取URI:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.http.server.reactive.ServerHttpRequest;
import reactor.core.publisher.Mono;

@RestController
public class DemoController {

    @GetMapping("/demo")
    public Mono<String> demo(@RequestHeader("Host") String host, ServerHttpRequest request) {
        // 通过请求是否安全推断scheme
        String scheme = request.isSecure() ? "https" : "http";
        int port = request.getURI().getPort();
        return Mono.just(String.format("Scheme: %s, Host: %s, Port: %d", scheme, host, port));
    }
}

该方式适合仅需部分属性的简单场景,无需全局传递上下文。


内容的提问来源于stack exchange,提问作者Sebastian Lore

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 17:40:28