Spring WebFlux函数式编程中如何获取客户端IP地址?
Hey there! I've dealt with this exact scenario before, so let me show you how to grab the client's IP address when working with Spring WebFlux's functional programming model using RouterFunction and ServerRequest.
Basic Approach: Use ServerRequest.remoteAddress()
The ServerRequest interface actually has a built-in method remoteAddress() that returns an Optional<InetSocketAddress>. You can use this to extract the client's IP directly. Here's a quick example:
import org.springframework.web.reactive.function.server.*; import static org.springframework.web.reactive.function.server.RequestPredicates.GET; import static org.springframework.web.reactive.function.server.RouterFunctions.route; public class IpRouter { public RouterFunction<ServerResponse> ipRoutes() { return route(GET("/api/client-ip"), request -> { // Extract client IP from remote address String clientIp = request.remoteAddress() .map(inetAddr -> inetAddr.getAddress().getHostAddress()) .orElse("Unknown IP"); // Use the IP as needed (log it, return it in response, etc.) System.out.println("Incoming request from IP: " + clientIp); return ServerResponse.ok().bodyValue("Your client IP is: " + clientIp); }); } }
Handling Reverse Proxies (e.g., Nginx, AWS ALB)
If your application is behind a reverse proxy, the remoteAddress() will return the proxy's IP instead of the actual client IP. In this case, you need to check common proxy headers like X-Forwarded-For or X-Real-IP. Here's a helper method to handle this:
private String getClientIp(ServerRequest request) { // Check X-Forwarded-For first (common for proxies) String xForwardedFor = request.headers().firstHeader("X-Forwarded-For"); if (xForwardedFor != null && !xForwardedFor.isBlank()) { // X-Forwarded-For can contain multiple IPs (client, proxy1, proxy2...) return xForwardedFor.split(",")[0].trim(); } // Fallback to X-Real-IP if available String xRealIp = request.headers().firstHeader("X-Real-IP"); if (xRealIp != null && !xRealIp.isBlank()) { return xRealIp; } // Final fallback to remote address return request.remoteAddress() .map(inetAddr -> inetAddr.getAddress().getHostAddress()) .orElse("Unknown IP"); }
You can then use this helper method in your router function like so:
return route(GET("/api/client-ip"), request -> { String clientIp = getClientIp(request); return ServerResponse.ok().bodyValue("Your actual client IP is: " + clientIp); });
Just a heads-up: Make sure your reverse proxy is configured to forward these headers correctly, otherwise they won't be present in the request. Also, if you're using Spring Security, you might want to configure it to trust the proxy to avoid security issues.
内容的提问来源于stack exchange,提问作者Sivannarayan

