Estoy tratando de mostrar un flujo de cadenas desde mi controlador a una vista en Thymeleaf, pero solo obtengo un ReactiveDataDriverContextVariable en la vista
Estoy usando Spring Boot 2
Este es mi código de controlador
@GetMapping("/demo") fun demo(model: Model): String{ val data = Flux.just("ONE", "TWO", "THREE", "FOUR") model.addAttribute("data", ReactiveDataDriverContextVariable(data,1)) return "demo" }Y este es mi código de plantilla Thymeleaf
<table class="table table-striped table-responsive"> <tr th:each="c: ${data}"> <td th:text="${c}">...</td> </tr> </table> Por lo que sé, ReactiveDataDriverContextVariable debería poner thymeleaf en un modo basado en datos y mostrar una lista de las cuatro cadenas, pero solo obtengo este resultado:
org.thymeleaf.spring5.context.webflux.ReactiveDataDriverContextVariable@30ece48Estoy seguro de que hay algo que me estoy perdiendo. Gracias de antemano.
EDITAR 1
Parece ser un problema con Spring Security
tengo esta configuracion habilitada
@EnableWebSecurity class SecurityConfig : WebSecurityConfigurerAdapter() { override fun configure(http: HttpSecurity) { http.authorizeRequests() .antMatchers("/demo") .permitAll() } }Cuando elimino la configuración y la dependencia de Spring Security, todo funciona bien, pero me gustaría proteger la aplicación web
¿algunas ideas?
Tuve el mismo problema. Mi problema era que, por otras razones, también tenía org.springframework.boot:spring-boot-starter-web como dependencia, por lo que thymeleaf no habilitó su modo reactivo.
Después de que lo eliminé, comenzó a funcionar, pero solo aceptaba un flujo y no podía generar un solo valor. Parece que solo admiten la iteración (th: each) en una transmisión, pero no pude encontrar una documentación adecuada, solo ejemplos de hola mundo.
Mi caso de uso era diferente. Simplemente no quería bloquear hasta que tenga mi único objeto de datos, así que se me ocurrió una solución que también funciona con -web. Aplacé el nombre de la vista hasta que reciba los datos del servidor. De esta manera, no necesito bloquear antes de devolver el nombre de la vista para iniciar la representación. (Este método solo funciona si no desea transmitir una lista larga) Para -webflux no necesita esta solución, simplemente coloque sus Monos y Fluxes en el modelo. Webflux los esperará automáticamente antes de llamar a thymeleaf.
Solución alternativa de WebMVC:
@GetMapping("/article/{articleId}/{friendlyUrl}") fun article(@PathVariable articleId: String, @PathVariable friendlyUrl: String, model: Model): Mono<String> { return gwDispatcher.dispatch(GetArticleGwCommand(articleId)).map { it.article }.map { model.addAttribute("article", it) model.addAttribute("name", "Josh Smith"); "article" } }