본문 바로가기
개발 관련됨/개발 이슈를 해결함

Springboot 에서 react.js 연동시 모든 view 맵핑을 index.html으로 forwarding 하는 방법은?

by simplify-len 2022. 4. 26.

 

[문제]

SpringBoot 에서 thymeleaf 대신, React.js 를 ViewTemplate 로 사용하려 한다.

기존의 thymeleaf 는 html 별로 View을 맵핑하고 있었기 때문에, 하나의 html 에서 URL에 따른 여러 화면으로 라우팅되는 SPA Application 에서는 ViewName 맵핑이 정상적으로 동작되지 않는다. ( 참고자료 )

 

예를 들어, product/list 라는 View 이름으로 맵핑을 시도한다고 가정해본다면,

프로젝트에서는

/WEB-INF/templates/product/list.html

와 같은 형태로 ViewTemplate 을 맵핑하기 위한 html 이 존재해야 합니다.(꼭, html 일 필요는 없음)

 

 그러므로, 하나의 html 에서 원하는 URL로 라우팅시키는 SPA Application(like react.js) 에서는 각 URL에 맵핑되는 html 이 있어야하는 TemplateEngine 과는 달리 html 이 없기 때문에 실제로 동작시켜보면 404가 발생합니다.

 

[원인]

 우리가 종종 보는 Frontend 와 Backend 를 나눈 형태는 아래와 같습니다.

흔한 FrontEnd 와 Backend

그러나, 만약 ViewTemplate 를 사용하는 경우는 Backend 안에서 Template Engine 의해 View가 그려지므로 아래와 같습니다.

그러므로, 다시 문제가 되었던 원하는 URL 로 라우팅이 되지 않는 문제를 하기 위해서는 어떻게 해야될까?

문제 원인

[해결]

해결은 간단명료합니다. ViewTemplate Engine 을 탐색할 때, 모든 URL 을 index.html 으로 forwarding 하도록 합니다.

여기 링크를 통해 답을 찾을 수 있었습니다.

 

WebMvcConfigurerAdapter 를 상속받은 WebConfiguration 을 만든다.

@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:/");
  }
}

이렇게 될 경우, /product/list 의 View 를 요청하는 경우, /WEB-INF/templates/product/list.html 를 찾는게 아니라, /index.html 로 forwarding 됩니다. 

 그 다음에 React 의 /product/list 의 라우터가 동작됩니다.

 

[참고 자료]

Spring catch all route for index.html

공식 thymeleaf 사이트

댓글