Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spring WebFlux doesn't handle redirect: directives when media type is requested [SPR-15291] #19857

Closed
spring-projects-issues opened this issue Feb 27, 2017 · 8 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: bug A general bug
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Feb 27, 2017

Greg Turnquist opened SPR-15291 and commented

The following code...

@Controller
public class WelcomeController {

    @GetMapping("/")
    @ResponseBody
    public String welcome() {
        return "Hello World";
    }

    @GetMapping("/redir")
    public Mono<String> redir() {
        return Mono.just("redirect:/");
    }
}

generates the following stacktrace...

java.lang.IllegalStateException: Could not resolve view with name 'redirect:/'.
    at org.springframework.web.reactive.result.view.ViewResolutionResultHandler.lambda$resolveViews$5(ViewResolutionResultHandler.java:274)

Affects: 5.0 M5

Issue Links:

Referenced from: commits 226c9f9, 718162b

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Feb 27, 2017

Greg Turnquist commented

See also #19103

@spring-projects-issues
Copy link
Collaborator Author

Rossen Stoyanchev commented

Greg Turnquist, I've added an integration test for this since we seem to be missing one and it does work with a FreemarkerViewResolver configured through the view resolver registry

Note that the "redirect:" prefix is detected in UrlBasedViewResolver or sub-classes such as FreemarkerViewResolver. So I'm wondering what view resolvers are in use? In other words what options are you invoking on the ViewResolverRegistry?

@spring-projects-issues
Copy link
Collaborator Author

Greg Turnquist commented

The precise code is here => https://github.com/learning-spring-boot/learning-spring-boot-2nd-edition-code/tree/master/3/part2.

It's a Thymeleaf-based project, so I drafted my own configuration here => https://github.com/learning-spring-boot/learning-spring-boot-2nd-edition-code/blob/master/3/part2/src/main/java/com/greglturnquist/learningspringboot/ReactiveThymeleafConfig.java

Spring Boot 2.0 doesn't yet have a Thymeleaf view resolver by default, so I built my own. I presume this is precursor to Boot adding such support?

@spring-projects-issues
Copy link
Collaborator Author

Rossen Stoyanchev commented

Okay thanks. WebFluxAnnotationAutoConfiguraiton appears to have support for auto-configuring ViewResolver beans. So assuming that part works fine. The ThymeleafReactiveViewResolver does not extend UrlBasedViewResolver but it does look for the "redirect:" prefix.

So I'm not sure what's going on. Sorry I did give your code a quick try but had trouble compiling. Perhaps you can debug a little to see why the view resolver does not pick up the prefix?

@spring-projects-issues
Copy link
Collaborator Author

Brian Clozel commented

Thymeleaf is now supported by Spring Boot (see spring-projects/spring-boot#8124). Custom auto-configuration is no longer needed.

I've just tested this against Spring Boot M1 + WebFlux and Thymeleaf starters and this seems to work as expected.

@spring-projects-issues
Copy link
Collaborator Author

Greg Turnquist commented

Okay, I finally tracked down what has been happening.

In the following code:

@DeleteMapping(value = BASE_PATH + "/" + FILENAME)
public Mono<String> deleteFile(@PathVariable String filename) {
	return Mono.just("redirect:/");
}

...WebFlux seeks out "best mediatype" in HandlerResultHandlerSupport. Using the Path-based resolver, a URI of :8080/images/foo.jpg will come up with acceptible type "image/jpeg". However, the producible type of this method, driven by the RedirectView, will generate text/html. These two media types do not align, and thus no "best mediatype" is found, resulting in an HTTP 406 getting thrown.

If the URI is altered to something else, like :8080/images/foo.jpg/delete, evading the Path-based resolver, this mismatch is avoided, and the redirect is carried out.

I couldn't apply anything in @DeleteMapping that seemed to make :8080/images/foo.jpg work properly, implying there is no way for such a URI to generate a redirect, a severe limitation.

Thoughts?

@spring-projects-issues
Copy link
Collaborator Author

Brian Clozel commented

Since you may have multiple file types associated with this endpoint, maybe dealing with the response "manually" is the best choice:

@GetMapping("/image.jpg")
public Mono<Void> redir(ServerWebExchange exchange) {
	ServerHttpResponse response = exchange.getResponse();
	response.setStatusCode(HttpStatus.SEE_OTHER);
	response.getHeaders().add(HttpHeaders.LOCATION, "/");
	return response.setComplete();
}

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented May 23, 2017

Rossen Stoyanchev commented

This looks like a bug. Arguably content negotiation should not impact redirects and I recall this being an issue once for Spring MVC (see #13254) and WebFlux should be consistent.

On the Spring MVC side SmartView extends View. I think in WebFlux we can add isRedirect to View as a default method and then it should be easy for ViewResolutionResultHandler to check if a candidate view is a redirect.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: bug A general bug
Projects
None yet
Development

No branches or pull requests

2 participants