10

I try to migrate my app from spring boot 1.5 to 2.0 The problem is that I cannot find EmbeddedServletContainerCustomizer. Any ideas how to make it through?

@Bean
public EmbeddedServletContainerCustomizer customizer() {
    return container -> container.addErrorPages(new ErrorPage(HttpStatus.UNAUTHORIZED, "/unauthenticated"));
}

Update: I found it as ServletWebServerFactoryCustomizer in org.springframework.boot.autoconfigure.web.servlet package.

@Bean
public ServletWebServerFactoryCustomizer customizer() {
    return container -> container.addErrorPages(new ErrorPage(HttpStatus.UNAUTHORIZED, "/unauthenticated"));
}

But there is an error: Cannot resolve method

'addErrorPages(org.springframework.boot.web.server.ErrorPage)'

I also had to change import of new Error Page from org.springframework.boot.web.servlet to org.springframework.boot.web.server

degath
  • 1,530
  • 4
  • 31
  • 60

4 Answers4

10

I think you need ConfigurableServletWebServerFactory, instead of ServletWebServerFactoryCustomizer.

You can find the code snippet below:

import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;

@Configuration
public class ServerConfig {

    @Bean
    public ConfigurableServletWebServerFactory webServerFactory() {
        UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory();
        factory.addErrorPages(new ErrorPage(HttpStatus.UNAUTHORIZED, "/unauthenticated"));
        return factory;
    }
}

The above code is for Undertow. For tomcat, you need to replace UndertowServletWebServerFactory with TomcatServletWebServerFactory.

You will need to add the following dependency to your project (in case of Maven):

<dependency>
    <groupId>io.undertow</groupId>
    <artifactId>undertow-servlet</artifactId>
    <version>2.0.26.Final</version>
</dependency>
Asu
  • 1,723
  • 2
  • 21
  • 32
6

You don't need the container customizer to register your error pages. Simple bean definition implemented as a lambda does the trick:

@Bean
public ErrorPageRegistrar errorPageRegistrar() {
    return registry -> {
        registry.addErrorPages(
            new ErrorPage(HttpStatus.UNAUTHORIZED, "/unauthenticated"),
        );
    };
}
Vadim Ferderer
  • 911
  • 7
  • 11
  • The question is which approach is better or where should we use the WebServerFactoryCustomizer instead? – Shilan Feb 27 '20 at 09:37
2

From Spring Boot 2 on the WebServerFactoryCustomizer has replaced the EmbeddedServletContainerCustomizer:

@Bean
public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> webServerFactoryCustomizer() {
    return (factory) -> factory.addErrorPages(new ErrorPage(HttpStatus.UNAUTHORIZED, "/401.html"));
}

Alternatively you might add a view controller like

@Override
public void addViewControllers(ViewControllerRegistry registry) {
    registry.addViewController("/unauthorized").setViewName("forward:/401.html");
}

and then your WebServerFactory should point to /unauthorized instead:

@Bean
public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> webServerFactoryCustomizer() {
    return (factory) -> factory.addErrorPages(new ErrorPage(HttpStatus.UNAUTHORIZED, "/unauthorized"));
}
Shilan
  • 813
  • 1
  • 11
  • 17
0

You can find the code snippet below:

@Bean
public ErrorPageRegistrar errorPageRegistrar(){
    return new MyErrorPageRegistrar();
}

// ...

private static class MyErrorPageRegistrar implements ErrorPageRegistrar {

    @Override
    public void registerErrorPages(ErrorPageRegistry registry) {
        registry.addErrorPages(new ErrorPage(HttpStatus.BAD_REQUEST, "/400"));
    }

}