Spring

Spring - WebMvcConfigurer Interface

dev_SiWoo 2023. 12. 8. 00:49

 

  WebMvcConfigurer는 Spring MVc를 사용하는 웹 APP에서 웹  MVC 구성을 사용자에 맞게 정의하는데 사용하는 인터페이스이다. 해당 인터페이스를 구현하여 Spring의 Web MVC 기능을 세밀하게 조정할 수 있다.

 

1. 정적 리소스 핸들링

/**
 * @Explain : Spring Boot에서 항상 index.html(React 앱의 엔트리 포인트)을 제공하도록 설정하여
 *          React Router가 클라이언트 사이드에서 적절하게 컴포넌트를 렌더링 할 수 있도록한다.
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Value("${cors.allowed.origin}")
    private String allowedOrigin;

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

        // news 이미지 파일 경로 설정
        registry.addResourceHandler("/imgs/news/**")
                .addResourceLocations("file:/HappyGames/news_imgs/");

        // React routing 설정
        registry.addResourceHandler("/**")
                .addResourceLocations("classpath:/static/")
                .resourceChain(true)
                .addResolver(new PathResourceResolver() {
                    @Override
                    protected Resource getResource(String resourcePath,
                                                   Resource location) throws IOException, IOException {
                        Resource requestedResource = location.createRelative(resourcePath);

                        return requestedResource.exists() && requestedResource.isReadable() ?
                                requestedResource : new ClassPathResource("/static/index.html");
                    }
                });
    }

  위 코드는 /imgs/news/ 경로에 대한 정적 리소스를 요청할 시, 해당 리소스가 위치하는 실제 경로를

파일 시스템의 /HappyGames/news_imgs/ 디렉토리로 지정하고 있다.

 

  또한 모든 HTTP요청('/**')에 대해 리소스 핸들러를  .addResourceLocations("classpath:/static/") 즉, 클래스 패스의 /static/디렉토리로 지정함으로써 Spring에서 React App의 엔트리 포인트를 제공하도록 설정하고 있다.

 

  이렇게 함으로써 Spring boot 서버가 클라이언트 사이드 라우팅을 위해 React 애플리케이션의 엔트리 포인트인 index.html을 항상 제공하도록 보장한다.

 

2. 인터셉터 등록

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new ChannelAccessInterceptor()).addPathPatterns("/friend/channel/**");
}

 

 

3. View Controller 추가용

  주로 간단한 웹 페이지를 컨트롤러 로직 없이 직접 뷰로 라우팅하는 경우

@RequrestMapping과 유하산 기능을 제공하지만, 뷰 이름만 반환하고 비즈니스 로직을 포함하지 않는 간단한 페이지 반환용도로 사용할 수 있다.

 

아래는 에러페이지를 반환하는 뷰 컨트롤러를 등록한 코드이다.

@Override
public void addViewControllers(ViewControllerRegistry registry) {
    registry.addViewController("/400").setViewName("error_page/400");
    registry.addViewController("/401").setViewName("error_page/401");
    registry.addViewController("/403").setViewName("error_page/403");
    registry.addViewController("/404").setViewName("error_page/404");
    registry.addViewController("/408").setViewName("error_page/408");
    registry.addViewController("/500").setViewName("error_page/500");
    registry.addViewController("/503").setViewName("error_page/503");
}

 

 

4. CORS 정책 설정

 다른 도메인에 의해 접근되어야 할 때 필요한 CORS 규칙을 정의할 수 있다.

@Override
public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/**") // 모든 URL 패턴에 대한 CORS 설정
            .allowedOrigins(allowedOrigin) // 127.0.0.1:8081 의 출처에서의 요청만 허용하도록 처리
            .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS");// 허용 메소드
}

 

 

5. 뷰 리졸버

  컨트롤러에서 반환된 뷰 이름이 실제 뷰 오브젝트로 변환되는 과정을 정의할 수 있다.
뷰가 리졸브드 되는 방식을 커스텀한 로직으로 변경할 수 있다.

@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
    InternalResourceViewResolver resolver = new InternalResourceViewResolver();
    resolver.setPrefix("/WEB-INF/views/");
    resolver.setSuffix(".jsp");
    registry.viewResolver(resolver);
}