스프링 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 안까먹을 듯.🥲)
결론은 되는 코드를 작성하기위해 일단 코드 수정부터 하고봤던 것이 삽질 시간을 왕왕 늘리게 되었던 것 같다...(각성..합시다!)
잘 보고 갑니다!