복붙노트

[SPRING] Spring에서 index.html에 대한 모든 경로 캐치

SPRING

Spring에서 index.html에 대한 모든 경로 캐치

클라이언트 측 라우팅을 위해 반응 라우터를 사용하는 반응 기반 단일 페이지 응용 프로그램을위한 스프링 백엔드를 개발 중입니다.

index.html 페이지 옆의 백엔드는 / api / ** 경로에있는 데이터를 제공합니다.

내 응용 프로그램의 루트 경로 /에 src / main / resources / public / index.html에서 index.html을 제공하기 위해 자원 처리기를 추가했습니다.

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/").addResourceLocations("/index.html");
}

내가 원하는 것은 다른 경로가 일치하지 않을 때마다 index.html 페이지를 제공하는 것입니다. / api가 아닌 다른 경로를 호출 할 때.

봄에 캐치 올 경로를 어떻게 구성합니까?

해결법

  1. ==============================

    1.내 반응 애플 리케이션이 앞으로 목표로 루트를 사용할 수 있기 때문에 결국이 일은 결국 끝났다.

    내 반응 애플 리케이션이 앞으로 목표로 루트를 사용할 수 있기 때문에 결국이 일은 결국 끝났다.

    @Configuration
    public class WebConfiguration extends WebMvcConfigurerAdapter {
    
      @Override
      public void addViewControllers(ViewControllerRegistry registry) {
          registry.addViewController("/{spring:\\w+}")
                .setViewName("forward:/");
          registry.addViewController("/**/{spring:\\w+}")
                .setViewName("forward:/");
          registry.addViewController("/{spring:\\w+}/**{spring:?!(\\.js|\\.css)$}")
                .setViewName("forward:/");
      }
    }
    

    솔직히 말해서 나는 무한 포워딩 루프를 피하기 위해 이것이 왜이 특정한 형식이어야하는지 잘 모른다.

  2. ==============================

    2.@EnableWebMvc 피하기

    @EnableWebMvc 피하기

    기본적으로 Spring-Boot는 src / main / resources의 정적 컨텐츠를 제공합니다.

    이것과 이것을보십시오;

    또는 @EnableWebMvc를 유지하고 addViewControllers를 재정의하십시오.

    @EnableWebMvc를 지정 했습니까? 자바 스프링 부트 : 내 응용 프로그램 루트 ( "/")를 index.html에 매핑하는 방법은 무엇입니까?

    @EnableWebMvc를 제거하거나 addViewControllers를 다시 정의 할 수 있습니다.

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

    또는 컨트롤러를 캐치 /

    github에서 spring-boot-reactjs 샘플 프로젝트를 살펴볼 수 있습니다.

    컨트롤러를 사용하여 원하는대로 작동합니다.

    @Controller
    public class HomeController {
    
        @RequestMapping(value = "/")
        public String index() {
            return "index";
        }
    
    }
    

    그것의 index.html은 src / main / resources / templates에있다.

  3. ==============================

    3.나는 Polymer 기반의 PWA를 Spring Boot 애플리케이션 내부에서 호스팅하고, 이미지와 같은 정적 인 웹 리소스와 "/ api / ..."아래의 REST API를 가지고있다. 클라이언트 쪽 응용 프로그램에서 PWA의 URL 라우팅을 처리하도록합니다. 여기 내가 사용하는 것이있다.

    나는 Polymer 기반의 PWA를 Spring Boot 애플리케이션 내부에서 호스팅하고, 이미지와 같은 정적 인 웹 리소스와 "/ api / ..."아래의 REST API를 가지고있다. 클라이언트 쪽 응용 프로그램에서 PWA의 URL 라우팅을 처리하도록합니다. 여기 내가 사용하는 것이있다.

    @Configuration
    public class WebConfig extends WebMvcConfigurerAdapter {
        /**
         * Ensure client-side paths redirect to index.html because client handles routing. NOTE: Do NOT use @EnableWebMvc or it will break this.
         */
        @Override
        public void addViewControllers(ViewControllerRegistry registry) {
            // Map "/"
            registry.addViewController("/")
                    .setViewName("forward:/index.html");
    
            // Map "/word", "/word/word", and "/word/word/word" - except for anything starting with "/api/..." or ending with
            // a file extension like ".js" - to index.html. By doing this, the client receives and routes the url. It also
            // allows client-side URLs to be bookmarked.
    
            // Single directory level - no need to exclude "api"
            registry.addViewController("/{x:[\\w\\-]+}")
                    .setViewName("forward:/index.html");
            // Multi-level directory path, need to exclude "api" on the first part of the path
            registry.addViewController("/{x:^(?!api$).*$}/**/{y:[\\w\\-]+}")
                    .setViewName("forward:/index.html");
        }
    
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/**").addResourceLocations("classpath:/webapp/");
        }
    }
    

    Angular 및 React 앱에서도 마찬가지입니다.

  4. ==============================

    4.이 질문을보고 답을 찾았습니다.

    이 질문을보고 답을 찾았습니다.

    @Bean
    public EmbeddedServletContainerCustomizer notFoundCustomizer() {
        return new EmbeddedServletContainerCustomizer() {
            @Override
            public void customize(ConfigurableEmbeddedServletContainer container) {
                container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/"));
            }
        };
    }
    
  5. ==============================

    5.내 봄 부팅 응용 프로그램에서 반응 및 반응 라우터를 사용하고 / / 및 / users / **와 같은 내 웹 사이트의 하위 트리에 매핑되는 컨트롤러를 만드는 것만 큼 쉽습니다. 여기 내 해결책이있다.

    내 봄 부팅 응용 프로그램에서 반응 및 반응 라우터를 사용하고 / / 및 / users / **와 같은 내 웹 사이트의 하위 트리에 매핑되는 컨트롤러를 만드는 것만 큼 쉽습니다. 여기 내 해결책이있다.

    @Controller
    public class SinglePageAppController {
        @RequestMapping(value = {"/", "/users/**", "/campaigns/**"})
        public String index() {
            return "index";
        }
    }
    

    API 호출은이 컨트롤러에 의해 포착되지 않으며 리소스가 자동으로 처리됩니다.

  6. ==============================

    6.여기에 / api 경로를 제외한 모든 경우에 단일 페이지 응용 프로그램 (SPA)을 제공하는 것과 관련된 특정 질문에 대답하려면 Petri의 대답을 수정해야합니다.

    여기에 / api 경로를 제외한 모든 경우에 단일 페이지 응용 프로그램 (SPA)을 제공하는 것과 관련된 특정 질문에 대답하려면 Petri의 대답을 수정해야합니다.

    내 SPA 용 index.html을 포함하는 polymer라는 이름의 템플릿이 있습니다. 그래서 과제는 / api와 / public-api를 제외한 모든 경로를 해당보기로 전달하도록했습니다.

    내 WebMvcConfigurerAdapter에서 addViewControllers를 재정의하고 정규 표현식을 사용했습니다. ^ ((!! / api / | / public-api /).)*$

    귀하의 경우 정규 표현식을 원한다. ^ ((?! / api /).)*$

    public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
    
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/{spring:^((?!/api/).)*$}").setViewName("polymer");
        super.addViewControllers(registry);
    }
    

    이렇게하면 SPA가 http : // localhost / api / posts, http로 성공적으로 라우팅되도록 내 SPA 및 나머지 모든 호출을 제공하기 위해 http : // localhost 또는 http : // localhost / community를 누를 수 있습니다 : // localhost / public-api / posts 등

  7. from https://stackoverflow.com/questions/39331929/spring-catch-all-route-for-index-html by cc-by-sa and MIT license