1

When I use org.springframework.boot:spring-boot-starter-web, I can remove Whitelabel error page and instead of it to show my message, when to link not found resource:

application.yml

server:
  error:
    whitelabel:
      enabled: false
spring:
  mvc:
    throw-exception-if-no-handler-found: true
  resources:
    add-mappings: false

NotFoundResource.class

@RestControllerAdvice
class NotFoundResource {

    @ExceptionHandler(NoHandlerFoundException.class)
    public String handleNotFoundResource() {

        return "Requested resource wasn't found on the server"
    }
}

How do I do it with webflux? In weblux doesn't contain NoHandlerFoundException.class.

Darkin Rall
  • 377
  • 1
  • 4
  • 17

1 Answers1

1

You can create your own ErrorWebExceptionHandler class for this requirement. Spring boot documentation gives insight on this.

[Quoted from documentation]

To change the error handling behavior, you can implement ErrorWebExceptionHandler and register a bean definition of that type. Because a WebExceptionHandler is quite low-level, Spring Boot also provides a convenient AbstractErrorWebExceptionHandler to let you handle errors in a WebFlux functional way, as shown in the following example

For a more complete picture, you can also subclass DefaultErrorWebExceptionHandler directly and override specific methods.

You can put some breakpoints on DefaultErrorWebExceptionHandler class and check how it works to render error response. Then based on your project requirement you can customize it for your need.

Here is a very simple thing I tried out.

CustomErrorWebExceptionHandler class:

public class CustomErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler {

  public CustomErrorWebExceptionHandler(
      ErrorAttributes errorAttributes,
      ResourceProperties resourceProperties,
      ApplicationContext applicationContext) {
    super(errorAttributes, resourceProperties, applicationContext);
  }

  @Override
  protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
    return route(all(), this::renderErrorResponse);
  }

  private Mono<ServerResponse> renderErrorResponse(ServerRequest serverRequest) {
    Throwable throwable = (Throwable) serverRequest
        .attribute("org.springframework.boot.web.reactive.error.DefaultErrorAttributes.ERROR")
        .orElseThrow(
            () -> new IllegalStateException("Missing exception attribute in ServerWebExchange"));

    if (throwable.getMessage().equals("404 NOT_FOUND \"No matching handler\"")) {
      return ServerResponse.status(HttpStatus.BAD_REQUEST).contentType(MediaType.APPLICATION_JSON)
          .body(Mono.just("Requested resource wasn't found on the server"), String.class);
    } else {
      return ServerResponse.status(HttpStatus.BAD_REQUEST).contentType(MediaType.APPLICATION_JSON)
          .body(Mono.just("Some Error happened"), String.class);
    }
  }

}

Create a bean from that class:

@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
@ConditionalOnClass(WebFluxConfigurer.class)
@AutoConfigureBefore(ErrorWebFluxAutoConfiguration.class)
public class Beans {

  @Bean
  @Order(-1)
  public CustomErrorWebExceptionHandler modelMapper(ErrorAttributes errorAttributes,
      ResourceProperties resourceProperties,
      ApplicationContext applicationContext, ServerCodecConfigurer serverCodecConfigurer,
      ObjectProvider<ViewResolver> viewResolvers) {

    CustomErrorWebExceptionHandler customErrorWebExceptionHandler = new CustomErrorWebExceptionHandler(
        errorAttributes, resourceProperties,
        applicationContext);

    customErrorWebExceptionHandler
        .setViewResolvers(viewResolvers.orderedStream().collect(Collectors.toList()));
    customErrorWebExceptionHandler.setMessageWriters(serverCodecConfigurer.getWriters());
    customErrorWebExceptionHandler.setMessageReaders(serverCodecConfigurer.getReaders());

    return customErrorWebExceptionHandler;
  }
}

application.properties:

server.error.whitelabel.enabled=false
spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false

This StackOverflow answer was helpful. https://stackoverflow.com/a/52508800/11251146

Community
  • 1
  • 1
Nipuna Saranga
  • 970
  • 13
  • 18