Cómo obtener la URL del método controlador de corriente en la primavera Webflux?

Johan:

Esta pregunta es similar a ¿Cuál es la mejor manera de obtener la URL actual en Spring MVC? pero para Webflux (que podría también estar relacionado con ¿Cómo obtener el contexto de la petición actual en primavera-webflux pero esta pregunta es más específica, así que espero que hay una solución).

Lo que quiero hacer es obtener una bodega de la URL actual en un controlador Webflux. Por ejemplo:

@GetMapping("/greeting")
public Mono<Greeting> greeting() {
   String linkToCurrentResource = .. // How do I get this?
   Greeting greeting = new Greeting("hello",  linkToCurrentResource);
   return Mono.just(greeting);
}

Preferiblemente linkToCurrentResourcedeben entender X-Forwarded-???cabeceras si se ejecuta detrás de un equilibrador de carga. Así que en este caso el que me gustaría linkToCurrentResourceser algo así https://external-uri.com/api/greeting. Estoy usando la implementación del servidor Netty si lo que importa.

CaCO3:

Se puede utilizar el ServerHttpRequestcomo parámetro para obtener el uri:

@RestController
public class GreetingController {
  @GetMapping("/greeting")
  public Mono<Greeting> getGreeting(ServerHttpRequest serverHttpRequest) {
    return Mono.just(new Greeting("greeting", serverHttpRequest.getURI().toString()));
  }
}

Preferiblemente linkToCurrentResourcedeben entender X-Forwarded-???cabeceras si se ejecuta detrás de un equilibrador de carga.

A continuación, puede exponer una .ForwardedHeaderTransformer @Bean

A partir de la documentación:

Valores Extracto de " Forwarded" y " X-Forwarded-*" cabeceras para anular la solicitud URI(es decir, HttpRequest.getURI()) por lo que refleja el protocolo y dirección del cliente-originado.

@Configuration
open class MvcConfig {
    @Bean
    open fun forwardedHeaderTransformer() = ForwardedHeaderTransformer()
}

Aquí hay algunas pruebas:

@ExtendWith(SpringExtension::class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT,
        properties = ["server.port=4333"])
class GreetingController2Test {
    @Autowired
    private lateinit var restTemplate: TestRestTemplate

    @Test
    fun `should return uri`() {
        val responseEntity = restTemplate.getForEntity("/greeting", Greeting::class.java)
        val greeting = responseEntity.body!!
        assertEquals("http://localhost:4333/greeting", greeting.uri)
    }

    @Test
    fun `should return uri composed from forwarded-??? headers`() {
        val headers = HttpHeaders()
        headers["X-Forwarded-Host"] = "external-uri.com"
        headers["X-Forwarded-Proto"] = "https"
        headers["X-Forwarded-Prefix"] = "/prefix"

        val httpEntity = HttpEntity(null, headers)
        val responseEntity = restTemplate.exchange("/greeting", HttpMethod.GET, httpEntity, Greeting::class.java)
        val greeting = responseEntity.body!!
        assertEquals("https://external-uri.com/prefix/greeting", greeting.uri)
    }
}

Y el Greeting.kt:

data class Greeting(
        val g: String? = null,
        val uri: String? = null
)

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=118149&siteId=1
Recomendado
Clasificación