404 Not Found 오류를 뿌셔보자!

김다희·2021년 9월 2일
2

스프링 jsp 강의를 수강하면서 따라해보는 과정에서 404 에러가...!
인터넷에서 아래와 관련된 오류 해결법을 다 따라해봐도 해결이되지 않고...(사람살려)

404 상태코드의 의미는
서버가 요청한 URL을 찾을 수 없음을 알려주기 위해 404 Not Found 사용한다고 합니다. 404 상태코드는 종종 클라이언트 애플리케이션이 사용자에게 보여주기 위한 entity가 포함되기도 합니다.

저 또한, 강의를 들으면서 http://localhost:8080/kdt_war_exploded/customers 라는 URL을 입력했을 때 맵핑할 수 없다는 로그가 서버에 찍혔습니다!

오류를 수정하기위해 아래의 3가지 방법을 시도해보았고, 3가지 방법을 시도해본뒤에도 오류는 여전했습니다!
1. URL 경로 확인 및 URL 과 관련된 코드 확인
2. 톰캣의 Deployment Artifact 재설정
3. 톰캣 제거 후 재설치

결과적으로 이런저런 삽질끝에 오류를 수정할 수 있었는데..! 그건 바로 componentScan의 범위때문에 발생한 오류였습니다! (정신차려!)

오류 발생 코드

public class KdtWebApplicationInitializer implements WebApplicationInitializer{

    @Configuration
    @EnableWebMvc
    @ComponentScan
    @EnableTransactionManagement
    static class AppConfig implements WebMvcConfigurer {

        ApplicationContext applicationContext;

        @Override
        public void configureViewResolvers(ViewResolverRegistry registry) {
            registry.jsp();
            
			//something
        }
    }

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
        applicationContext.register(AppConfig.class);

        DispatcherServlet dispatcherServlet = new DispatcherServlet(applicationContext);
        ServletRegistration.Dynamic servletRegistration =servletContext.addServlet("test", dispatcherServlet);
        servletRegistration.addMapping("/");
        servletRegistration.setLoadOnStartup(1);
    }
}

오류 수정 코드

public class KdtWebApplicationInitializer implements WebApplicationInitializer{

    @Configuration
    @EnableWebMvc
    @ComponentScan(basePackages = {"org.prgrms.kdt"})
    @EnableTransactionManagement
    static class AppConfig implements WebMvcConfigurer {

        ApplicationContext applicationContext;

        @Override
        public void configureViewResolvers(ViewResolverRegistry registry) {
            registry.jsp();
            
			//something
        }
    }

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
        applicationContext.register(AppConfig.class);

        DispatcherServlet dispatcherServlet = new DispatcherServlet(applicationContext);
        ServletRegistration.Dynamic servletRegistration =servletContext.addServlet("test", dispatcherServlet);
        servletRegistration.addMapping("/");
        servletRegistration.setLoadOnStartup(1);
    }
}

수정한 부분은 딱 1줄, @ComponentScan(basePackages = {"org.prgrms.kdt"}) 이 부분인데요.
@ComponentScan 스캔 범위에 대해서 다시 짚어보고 가자면,
@ComponentScan이 명시된 클래스가 위치한 디렉토리를 포함한 그 하위 디렉토리를 스캐닝합니다.

  • 수정 전 @ComponentScan 범위는 KdtWebApplicationInitializer가 속해있는 org.prgrmas.kdt.servlet 패키지 하위부터 scan이 됩니다.

  • 수정 후 @ComponentScan 범위는 org.prgrmas.kdt 패키지 하위부터 scan이 됩니다.

결과적으로 수정한 코드가 정상적으로 돌아가는 이유는

AnnotationConfigWebApplicationContext에 org.prgrms.kdt 하위 빈들이 등록이 되어야하고 스캔 범위를 org.prgrmas.kdt.servlet 패키지 하위에서 org.prgrmas.kdt 하위까지 모두 불러올 수 있도록 스캔 범위를 바꿔주었기 때문입니다.


오류 수정이 어려웠던 이유
1. ComponentScan 범위에 대해서 제대로 인지하지 못했음.(내가 아는게 아는게 아니여~반성..하자..각성..하자..)
2. AnnotationConfigWebApplicationContext 동작에 대해서 제대로 인지하지 못했음. 이 이후 강의에 AnnotationConfigWebApplicationContext 대한 설명이 나오는것도 있지만, 오류가 났을 때 AnnotationConfigWebApplicationContext가 어떻게 동작하는지 찾아봤더라면 삽질 시간을 줄일 수 있었을 것 같음.

오류 수정을 하기위해서 삽질을 계속 하다보면 "아! 나 지금 어떤 개념을 단단히 놓치고 있네. 뭘 모르는거지?" 라는 생각이 들때가 있다. 그런 느낌이 드는 상태에서 어찌저찌 오류를 수정하고나면, 내가 뭘 몰라서 한참이나 헤매였는지 명확하게 보이게된다. 아직은 "뭘 모르는지를 빠르게 알아채는 힘"이 부족한 느낌.. 분발하자! (그래도 삽질덕에.. 놓쳤던 개념에 대해서 제대로 배웠다. 관짝에 들어가기 전까진 ComponentScan 안까먹을 듯.🥲)

결론은 되는 코드를 작성하기위해 일단 코드 수정부터 하고봤던 것이 삽질 시간을 왕왕 늘리게 되었던 것 같다...(각성..합시다!)


@ComponentScan 이 무엇인지 다시 찾아보자..

profile
개발 덕질 중(?)

1개의 댓글

comment-user-thumbnail
2021년 9월 5일

잘 보고 갑니다!

답글 달기