programing

404를 단일 페이지 앱으로 리디렉션하도록 스프링 부팅 구성

i4 2023. 6. 20. 21:21
반응형

404를 단일 페이지 앱으로 리디렉션하도록 스프링 부팅 구성

Spring Boot 앱을 구성하여 404 not found 요청을 단일 페이지 앱으로 리디렉션하려고 합니다.

예를 들어 내가 전화하는 경우localhost:8080/asdasd/asdasdasd/asdasd존재하지 않는 경우, 다음으로 리디렉션해야 합니다.localhost:8080/notFound.

문제는 단일 페이지 대응 앱이 있고 루트 경로에서 실행된다는 것입니다.localhost:8080/그래서 봄은 방향을 바꾸어야 합니다.localhost:8080/notFound그리고 나서 앞으로./(경로 유지).

다음은 전체 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"));
    };
  }

}

이렇게 하면 효과가 있습니다.라우팅 대상 404에 대한 오류 페이지 추가/notFoundSPA로 전송합니다(입력이 켜져 있다고 가정)./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"));
        };
    }

}

Spring Boot 앱에서 Angular/React/기타 경로 및 경로를 처리하는 방법을 찾는 사람이 있지만 404에 대해 항상 index.html을 반환하지는 않는 경우 표준 Spring 컨트롤러 Request Mapping에서 수행할 수 있습니다.이 작업은 보기 컨트롤러를 추가하거나 컨테이너 오류 페이지를 사용자 지정하지 않고도 수행할 수 있습니다.

RequestMapping은 와일드카드를 지원하므로 응용 프로그램에서 잘 알려진 경로 집합(예: 각 경로 등)과 일치하도록 만든 다음 forward index.html을 반환합니다.

@Controller 
public class Html5PathsController { 

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

다른 옵션(여기에 있는 https://spring.io/blog/2015/05/13/modularizing-the-client-angular-js-and-spring-security-part-vii) 의 오래된 Spring 기사에서 제외)은 이름 지정 규칙을 사용하는 것입니다.

@Controller 
public class Html5PathsController { 

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

위의 구성은 기간을 포함하지 않고 다른 컨트롤러에 아직 매핑되지 않은 모든 경로와 일치합니다.

//add this controller : perfect solution(from jhipster)
@Controller
public class ClientForwardController {
    @GetMapping(value = "/**/{path:[^\\.]*}")
    public String forward() {
        return "forward:/";
    }
}

여기서 보안 구성(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());
    }
}

찾을 수 없는 경우 오류 페이지로 리디렉션

@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;
    }
}

다음과 같은 오류 페이지

<!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>

org.springframework.boot.web.servlet.error구현하기만 하면 됩니다.오류 제어기가 저를 대신했습니다.저는 React와 함께 SpringBoot 2.0을 사용합니다. (만약 그것을 하는 방법에 관심이 있다면 여기 제가 만든 보일러 플레이트 프로젝트가 있습니다: https://github.com/archangel1991/react-with-spring)

@Controller
public class CustomErrorController implements ErrorController {

    @Override
    public String getErrorPath() {
        return "/error";
    }
}

근데 이게 왜 효과가 있는지 잘 모르겠어요.

언급URL : https://stackoverflow.com/questions/44692781/configure-spring-boot-to-redirect-404-to-a-single-page-app

반응형