본문 바로가기
끄적/노트

[SpringBoot] 패키징 된 war 배포를 위해 vue의 정적파일 매핑하기

by 밀키스 2024. 3. 11.

 상황 

  1. SpringBoot와 vue를 war로 패키징하여 서버에 배포하고자 함.
  2. 각각의 프로젝트를 독립적으로 실행했을 때와 다르게 첫화면과 메인화면을 제외하고 404 에러가 뜸
  3. 원인은 vue의 정적파일인 index.html로 찾아가지 못함.

 

해결

SpringBoot의 WebConfig 내 addResourceHandlers를 추가하여 해결 함.

 

@Configuration
public class WebConfig implements WebMvcConfigurer {
   @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**")
                .addResourceLocations("classpath:/static/")
                .resourceChain(true)
                .addResolver(new CustomPathResourceResolver());
    }
    
    private static class CustomPathResourceResolver extends PathResourceResolver {
        @Override
        protected Resource getResource(String resourcePath, Resource location) {
            try {
                Resource requestedResource = location.createRelative(resourcePath);
                if (requestedResource.exists() && requestedResource.isReadable()) {
                    return requestedResource;
                } else {
                    return new ClassPathResource("/static/index.html");
                }
            } catch (Exception e) {
                return null;
            }
        }
    }
}

 

  • addResourceHandlers: SpringBoot에 사용할 정적 리소스 처리와 관련된 기본 설정을 변경할 수 있는 WebMvcConfigurer 인터페이스를 통해 구현하는 메서드
  • addResourceHandler: 요청된 URL의 패턴을 지정, 해당 패턴에 대한 정적 리소스 처리 담당 핸들러를 추가한다. 본인의 경우 "/**" 와 같은 표현을 통해 모든 요청에 대한 처리를 하고자 했다.
  • addResourceLocations: 요청된 URL에 해당하는 정적 파일을 지정한다.
    • SpringBoot는 정적 리소스 처리를 위해 < /static, /public, /resources, /META-INF/resources>를 자동으로 찾는다.
    • 때문에 src/main 아래에 있던 build/resources 아래에 있던 static 폴더 내에 정적 리소스가 있다면 찾는다.
    • 하지만 src/main/static에 위치되었다고 가정할 때 해당 경로를 명시해주면 에러가 발생한다... 관련 공식 문서를 뒤져 보았으나 아직 이해도가 부족한듯 하다...
  • addResourceChain: resourceChain을 활성화하면 다수의 Resolver를 사용하여 요청된 리소스를 찾을 수 있다고 함.
  • addResolver: SpringBoot가 요청된 리소스를 해석할 때 사용하는 ResourceResolver를 추가한다. 단순 추가가 아닌 위 처럼 지정된 동작을 수행하여 추가할 수도 있다.
    • createRelative는 Resource의 상대 경로에 위치한 다른 리소스에 접근할 수 있다. 예로 location이 A/B에 위치하고, resourcePath의 값이 test라고 할 때. A/B/test에 접근 가능한 것.
    • 가져온 리소스의 경로가 존재하지 않을 때 index.html을 찾아갈 수 있도록 한다.

 

 


 

위와 같은 설정을 통해 SpringBoot와 vue를 패키징하여 war로 배포했을 때, 정상 동작하도록 수행하였다.

 

다른 해결책으로 ErrorController를 상속 받는 CustormErrorController를 만들어 "/Error"에 매핑되는 Handler 메소드를 만들고 index.html이 return되도록 해보았을 때도 같은 결과가 나온다.

 

하지만.. 근본적인 해결책은 아닌듯 하여 본문과 같은 해결을 택하였다. 

반응형

댓글