MVC와 View 파악

22_gas·2024년 6월 21일
    1. 4 작성됨

개요

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

사용중인 jsp 파일은 "webapp/WEB-INF/view/" 아래에 위치 하게 된다.

이렇게 된 경우

http://localhost:8080/main/env/page.do (정상)
http://localhost:8080/main/env/folder/page.do (404)... < 안뜬다....왜 안뜨는걸까?

Sprin 설정을 하나하나 까봐야될거 같다.

원인을 찾아서

1.ViewContoller

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 &quot;/WEB-INF/view/main/env/folder.page.jsp&quot; 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));
}

이렇게 하니 정상적으로 화면을 불러오는것을 확인했다.

2.servlet.xml

다음은 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을 이용하기 때문에 해당 설정을 확인한다.

3.tiles.xml

설정파일에 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하면 된다.

후기

스프링은 설정 하나하나 알아가느 재미가 쏠쏠하다. ㅋㅋ

profile
전 아직 모르는게 많아요

0개의 댓글