회사일을하던중 굉장히 흥미로운 현상을 마주하게 된다.

사용중인 jsp 파일은 "webapp/WEB-INF/view/" 아래에 위치 하게 된다.
이렇게 된 경우
http://localhost:8080/main/env/page.do (정상)
http://localhost:8080/main/env/folder/page.do (404)... < 안뜬다....왜 안뜨는걸까?
Sprin 설정을 하나하나 까봐야될거 같다.
viewController 를 확인 해보기로 했다.
@RequestMapping("{path}")
public ModelAndView view(Model model, @PathVariable("path") String path) {
return new ModelAndView(String.format("main.env.%s", path));
}
※여기에 path가 추가된 매핑을 추가한다.
@RequestMapping("{path1}/{path2}")
public ModelAndView view2(Model model, @PathVariable("path1") String path1, @PathVariable("path2") String path2) {
return new ModelAndView(String.format("main.env.%s.%s", path1, path2));
}
이렇게 돌리니 아래와 같은 에러가 발생
1월 04, 2023 3:40:13 오후 org.apache.catalina.core.StandardWrapperValve invoke
심각: Servlet.service() for servlet [spring] in context with path [] threw exception [Request processing failed; nested exception is org.apache.tiles.request.render.CannotRenderException: java.io.IOException: JSPException including path '/WEB-INF/view/main/env/foler.page.jsp'.] with root cause
javax.servlet.ServletException: File "/WEB-INF/view/main/env/folder.page.jsp" not found
at org.apache.jasper.servlet.JspServlet.handleMissingResource(JspServlet.java:417)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:384)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:339)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(
※ 왜 뒷부분이 folder.page.jsp가 되었을까?
일단 ModelAndView에 "/"가 포함된 경로면 가능할것 같아서 아래와같이 "/"로 변경하여 돌렸다.
@RequestMapping("{path1}/{path2}")
public ModelAndView view2(Model model, @PathVariable("path1") String path1, @PathVariable("path2") String path2) {
return new ModelAndView(String.format("main/env/%s/%s", path1, path2));
}
이렇게 하니 정상적으로 화면을 불러오는것을 확인했다.
다음은 servlet.xml 설정을 확인해보기로했다.
<!-- tiles -->
<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
<property name="definitions">
<list>
<value>classpath:tiles/tiles.xml</value>
</list>
</property>
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.tiles3.TilesView" />
</bean>
<bean id="viewResolver1" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
</bean>
viewResolver
InternalResourceViewResolver: 웹 어플리케이션의 WAR파일 내에 포함된 뷰 템플릿을 찾는다.
뷰 템플릿의 경로는 논리적 뷰 이름에 접두어와 접미어를 붙여 구성
UrlBasedViewResolver: ViewResolver의 구현체로 특별한 매핑 정보 없이 view 이름을 URL로 사용
View이름과 실제 view 자원과의 이름이 같을 때 사용한다.
viewResolver에서 view 페이지를 찾을 때 tile을 이용하기 때문에 해당 설정을 확인한다.
설정파일에 tiles.xml 이 존재한다.
<. 생략 .>
<definition name="*.*.*" extends="base.main">
<put-attribute name="body" value="/WEB-INF/view/{1}/{2}/{3}.jsp" />
</definition>
<definition name="*.*" extends="base.main">
<put-attribute name="body" value="/WEB-INF/view/{1}/{2}.jsp" />
</definition>
※ 원인을 찾았다. 바로 이설정 때문에
new ModelAndView("main.env.page"); => /WEB-INF/view/main/env/page.jsp 를 찾는것이고
new ModelAndView("main.env.folder.page"); => /WEB-INF/view/main/env/page.page.jsp 를 찾는 것이었다.
하여 아래와 같은 설정을 추가하면 정상적으로 화면이 표출되게 된다.
<definition name="*.*.*.*" extends="base.main">
<put-attribute name="body" value="/WEB-INF/view/{1}/{2}/{3}/{4}.jsp" />
</definition>
servlet.xml 에서 viewResolver가 추가되며 tiles설정으로 넘긴다.
tiles.xml에서 '*.*.*'을 .jsp 파일찾는 경로로 바꿔준다.
만약 tile 설정 viewResolver가 없다면 Controller에서 "main/env/folder/page"로 만들어서 return하면 된다.
스프링은 설정 하나하나 알아가느 재미가 쏠쏠하다. ㅋㅋ