Home > Enterprise >  Is there a way to get request URI in Spring
Is there a way to get request URI in Spring

Time:10-08

Whenever a request is made, I need to get request URI for some internal calculations. For some time I've been doing it like this:t

public Mono<Response> example(ServerHttpRequest req) { ... }

And then using req.getURI(). But that becomes a pain once you need to pass this down multiple times. I need the URI object to extract scheme, schemeSpecificPart, host, port from it.

Is there a way to get these properties without extracting them from a request?

UPD: I see that for Web MVC there are convenient methods to retrieve request URI. But I need the same for reactive stack (netty).

CodePudding user response:

You can try this :

public Mono<Response> example(WebRequest request){
           System.out.println(request.getDescription(false));
        .......
    }

You can turn this false to true in getDescription as false will only give you the Uri which i think is the only thing you need.

CodePudding user response:

You can inject it in any bean.

@Autowired
private HttpServletRequest request;

CodePudding user response:

It can be achieved by creating WebFilter that puts ServerHttpRequest into the Context:

@Component
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
public class ReactiveRequestContextFilter implements WebFilter {
  @Override
  public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
    ServerHttpRequest request = exchange.getRequest();
    return chain
        .filter(exchange)
        .contextWrite(ctx -> ctx.put(ReactiveRequestContextHolder.CONTEXT_KEY, request));
  }
}

Additionally, create class that provides static access to request data:

public class ReactiveRequestContextHolder {
  public static final Class<ServerHttpRequest> CONTEXT_KEY = ServerHttpRequest.class;

  public static Mono<ServerHttpRequest> getRequest() {
    return Mono.deferContextual(Mono::just).map(ctx -> ctx.get(CONTEXT_KEY));
  }

  public static Mono<URI> getURI() {
    return getRequest().map(HttpRequest::getURI);
  }
}

Methods can be accessed through the class name directly without having to instantiate them. Just be careful to not access it before the filter is executed.

Example of usage:

@RestController
@RequestMapping
public class TestController {
  @GetMapping("/test")
  public Mono<URI> test() {
    return ReactiveRequestContextHolder.getURI();
  }
}

Reference

  • Related