web-dev-qa-db-fra.com

Configurez Spring Boot pour rediriger 404 vers une application à une seule page

Je souhaite configurer mon application Spring Boot pour rediriger toute demande 404 non trouvée vers mon application à page unique.

Par exemple, si j'appelle localhost:8080/asdasd/asdasdasd/asdasd qui n'existe pas, il devrait être redirigé vers localhost:8080/notFound.

Le problème est que je n'ai qu'une seule page qui réagit et qu'elle s'exécute dans le chemin d'accès racine localhost:8080/. Donc, spring devrait rediriger vers localhost:8080/notFound et ensuite transmettre à / (pour garder la route).

7
Vovan

Cela devrait faire l'affaire: ajoutez une page d'erreur pour 404 qui route vers /notFound et transmettez-la à votre SPA (en supposant que l'entrée est sur /index.html):

@Configuration
public class WebApplicationConfig extends WebMvcConfigurerAdapter {

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


    @Bean
    public EmbeddedServletContainerCustomizer containerCustomizer() {
        return container -> {
            container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND,
                    "/notFound"));
        };
    }

}
16
Ralf Stuckert

Voici l'exemple complet de Spring Boot 2.0:

@Configuration
public class WebApplicationConfig implements WebMvcConfigurer {

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


@Bean
public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> containerCustomizer() {
    return container -> {
        container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND,
                "/notFound"));
    };
  }

}
7

Au cas où quelqu'un trébucherait ici pour savoir comment gérer les routes et les chemins angulaires/React/autres dans une application Spring Boot - mais ne renvoie pas toujours index.html pour un 404 - cela peut être effectué dans un contrôleur Spring standard RequestMapping. Cela peut être fait sans ajouter de contrôleurs de vue et/ou personnaliser la page d'erreur du conteneur.

RequestMapping prend en charge les caractères génériques, vous pouvez donc le faire correspondre à un ensemble de chemins bien connus (par exemple, des itinéraires angulaires, etc.) dans votre application et ensuite seulement renvoyer index.html: 

@Controller 
public class Html5PathsController { 

    @RequestMapping( method = {RequestMethod.OPTIONS, RequestMethod.GET}, path = {"/path1/**", "/path2/**", "/"} )
    public String forwardAngularPaths() { 
        return "forward:/index.html"; 
    } 
}

Une autre option (empruntée à un ancien article de Spring ici: https://spring.io/blog/2015/05/13/modularizing-the-client-angular-js-and-spring-security-part-vii ) consiste à utiliser une convention de dénomination:

@Controller 
public class Html5PathsController { 

    @RequestMapping(value = "/{[path:[^\\.]*}")
    public String redirect() {
        return "forward:/index.html";
    } 
}

La configuration ci-dessus correspond à tous les chemins qui ne contiennent pas de période et qui ne sont pas déjà mappés vers un autre contrôleur. 

2
joensson

Ici la configuration de la sécurité (SecurityConfig.Java)

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private Environment env;

    @Autowired
    private UserSecurityService userSecurityService;

    private BCryptPasswordEncoder passwordEncoder() {
        return SecurityUtility.passwordEncoder();
    }

    private static final String[] PUBLIC_MATCHERS = {
            "/css/**",
            "/js/**",
            "/data/**",
            "/sound/**",
            "/img/**",
            "/",
            "/login",
            "/logout,
            "/error",
            "/index2",
    };

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests().
        /*  antMatchers("/**").*/
            antMatchers(PUBLIC_MATCHERS).
            permitAll().anyRequest().authenticated();
        //.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login");

        http
            .csrf().disable().cors().disable()
            .formLogin().failureUrl("/login?error")
            .defaultSuccessUrl("/index2")
            .loginPage("/login").permitAll()
            .and()
            .logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
            .logoutSuccessUrl("/?logout").deleteCookies("remember-me").permitAll()
            .and()
            .rememberMe()
            .and()
            .sessionManagement().maximumSessions(3600)
            .and().
            invalidSessionUrl("/login");
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userSecurityService).passwordEncoder(passwordEncoder());
    }
}

Si non trouvé aucune ressource rediriger vers la page d'erreur

@Controller
public class IndexController implements ErrorController{

    private static final String PATH = "/error";

    @RequestMapping(value = PATH)
    public String error() {
        return PATH;
    }

    @Override
    public String getErrorPath() {
        return PATH;
    }
}

Page d'erreur comme

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1000/xhtml"
    xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
    <meta http-equiv="refresh" content="5;url=/login" />
<body>
 <h1>Page not found please login the system!</h1>
</body>
</html>
1
Md. Maidul Islam