Redirection inside reactive Spring Webflux REST controller
Asked Answered
M

2

12

I'm creating simple controller server for spring reactive project. While setting redirection to another location, I have found an error when calling http://localhost:8080/:

There was an unexpected error (type=Internal Server Error, status=500).
ModelAttributeMethodArgumentResolver does not support multi-value reactive type wrapper: interface reactor.netty.http.server.HttpServerResponse
java.lang.IllegalStateException: ModelAttributeMethodArgumentResolver does not support multi-value reactive type wrapper: interface reactor.netty.http.server.HttpServerResponse
    at org.springframework.util.Assert.state(Assert.java:94)
    at org.springframework.web.reactive.result.method.annotation.ModelAttributeMethodArgumentResolver.resolveArgument(ModelAttributeMethodArgumentResolver.java:112)
    at org.springframework.web.reactive.result.method.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:123)
    at org.springframework.web.reactive.result.method.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:190)
    at org.springframework.web.reactive.result.method.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:133)
    at org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerAdapter.lambda$handle$1(RequestMappingHandlerAdapter.java:200)
    at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:44)
...

This is the controller code:

import reactor.core.publisher.Mono;
import reactor.netty.http.server.HttpServerResponse;

@RestController
public class BaseController {
    @GetMapping("/")
    public Mono<Void> indexController(HttpServerResponse response) {

        return response.sendRedirect("/api/v1");
    }
// ...
}

I expected it to be redirected from localhost:8080/ to localhost:8080/api/v1. But I've got the above exception.

Massimo answered 9/9, 2019 at 12:0 Comment(1)
Did you try it this way? Possible duplicate #50502877Lowrie
L
19

Redirecting with Controller MVC good-old approach:

import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

import java.net.URI;

@RestController
public class Controller {
    @GetMapping("/")
    public Mono<Void> indexController(ServerHttpResponse response) {
        response.setStatusCode(HttpStatus.PERMANENT_REDIRECT);
        response.getHeaders().setLocation(URI.create("/api/v1"));
        return response.setComplete();
    }
}

If someone would prefer functional Router/Handler approach might investigate: How to redirect a request in spring webflux?.

@Bean
RouterFunction<ServerResponse> routerFunction() {
    return route(GET("/"), req ->
            ServerResponse.temporaryRedirect(URI.create("/api/v1"))
                    .build());
}
Lowrie answered 28/9, 2019 at 9:18 Comment(1)
how can i add request attributes / post body payload?Fug
M
6

When using @RestController a ResponseEntity can work as well (here implemented using kotlin coroutines) :

@RestController
class SomeController() {
  suspend fun someMethod() : ResponseEntity<Unit> {
    return ResponseEntity
      .status(HttpStatus.TEMPORARY_REDIRECT)
      .location(URI.create("/api/v1"))
      .build()
  }
}
Manganous answered 30/8, 2021 at 18:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.