Affects: 6.1

RFE: add a section in WebFlux “View Technologies” on how to do forward: and redirect:.

Currently it's not obvious how to handle these schemes with a multitude of SO posts.

Somehow I think the library should be able to handle it easily.

Aside: redirect: seems to be available in UrlBasedViewResolver : but the docs don't show how to add that to the registry (the docs have a freemarker example though).

package com.example.demos;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import reactor.core.publisher.Mono;

@SpringBootApplication
@Controller
public class DemoExodusApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoExodusApplication.class, args);
    }

    @GetMapping("/hello")
    Mono<String> hello() {
        return Mono.just("forward:/goodbye");
    }

    @ResponseBody
    @GetMapping("/goodbye")
    Mono<String> goodbye() {
        return Mono.just("{\"message\":\"goodbye\"}");
    }
}

Neither of these two patterns work and there is an exception such as:

java.lang.UnsupportedOperationException: Forwards are not currently supported by ThymeleafReactiveViewResolver
    at org.thymeleaf.spring6.view.reactive.ThymeleafReactiveViewResolver.resolveViewName(ThymeleafReactiveViewResolver.java:984) ~[thymeleaf-spring6-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 

Without Thymeleaf:

java.lang.IllegalStateException: Could not resolve view with name 'forward:/goodbye'.
    at org.springframework.web.reactive.result.view.ViewResolutionResultHandler.lambda$resolveViews$3(ViewResolutionResultHandler.java:275) ~[spring-webflux-6.1.12.jar:6.1.12]
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 

Comment From: bclozel

This part is documented in the "Redirecting" section of our reference documentation.

I have successfully tested this feature with the mustache templating engine.

It seems this feature is not supported by all templating engines, such as Thymeleaf. Even if we don't support this engine ourselves it is very popular so we could add a note about this in the docs. Would that work for you?

Comment From: space88man

It seems this feature is not supported by all templating engines, such as Thymeleaf. Even if we don't support this engine ourselves it is very popular so we could add a note about this in the docs. Would that work for you?

It would be good to note: - a templating engine is mandatory (e.g. mustache). Otherwise the view "redirect:/goodbye' is not resolvable. With mustache in pom.xml I can indeed redirect from /hello to /goodbye

  • (as you pointed out) some templating engines don't support "redirect:"

  • can redirects/forward to a controller work without a template engine configured?

  • what if I don't want a redirect but an internal "forward:/goodbye" — how can this be achieved? Are we supposed to punt back to DispatcherHandler?

@Autowired
DispatcherHandler dispatcherHandler;

Mono<Void> hello() {
   // emulate MVC forward:
  exchange = exchange.mutate(... change request path to /goodbye...);
   // punt to DispatcherHandler;
  return this.dispatcherHandler.handle(exchange);
}

Comment From: bclozel

It would be good to note: * a templating engine is mandatory (e.g. mustache). Otherwise the view "redirect:/goodbye' is not resolvable. With mustache in pom.xml I can indeed redirect from /hello to /goodbye

A String return value (without the @ResponseBody) refers to a ViewResolver and View technologies. I'm not sure how we can improve the documentation there.

can redirects/forward to a controller work without a template engine configured?

I think so, yes. This is covered I think in the "redirecting" section I pointed to and in the javadocs.

what if I don't want a redirect but an internal "forward:/goodbye" — how can this be achieved? Are we supposed to punt back to DispatcherHandler?

Unlike MVC, Forward dispatches are not supported in WebFlux. See #19106. I think other projects chose to use DispatcherHandler directly, but I'm not sure this is a supported case on our side.