Tiny Bunny [Spring] ViewResolver 사용과 Spring 흐름 정리 - 솜님의 블로그
솜님의 블로그
카테고리
작성일
2024. 10. 8. 16:29
작성자
겨울솜사탕

페이지에 데이터를 반드시 출력해야 할 때

ex) 상세보기

     - 네이버 웹툰에서 url에 없는 회차번호를 입력해서 이동시키면,  다시 웹툰 목록을 보여준다.

     - 만약 이런 상황에 대한 것을 만들어두지 않았다면 빈 화면으로 나올 것이다.

     - 이런 걸 반드시 설정해줘야 한다.

페이지에 들어갈 때 인증을 반드시 해야 할 때

ex) 관리자 페이지, 사장님 페이지

 

 

이런 식으로 페이지를 만들다 보면 제한적으로 뭔갈 해줘야 하는 상황이 생길 수 있다.

이걸 해결하는 방식은 다양한데, 오늘은 한 가지 방법에 대해 알아본다!

 

 


 

JSP 파일을 만들 때 WEB-INF 하위에 JSP 파일을 생성하게 되면

오류가 발생하고, WEB-INF 하위에 있는 것은 클라이언트(사용자, 브라우저)가 찾아갈 수 없다.

 

그래서 WEB-INF 하위에 views라는 폴더를 하나 만들어서, 이 안에 기존 main.jsp 파일(실습파일)을 넣어준다.

( xml 파일과 구분하기 위해 폴더를 만들어줌)

 

Q. main.jsp와 login.jsp의 차이점은?

 

// login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인 페이지</title>
</head>
<body>

<form action="login.do" method="POST">
<table border="1">
	<tr>
		<td>아이디</td>
		<td><input type="text" name="mid" required></td>
	</tr>
	<tr>
		<td>비밀번호</td>
		<td><input type="password" name="password" required></td>
	</tr>
	<tr>
		<td colspan="2" align="right"><input type="submit" value="로그인"></td>
	</tr>
</table>
</form>

</body>
</html>

 

 

// main.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>메인 페이지</title>
</head>
<body>

<h1>로그인 성공시 메인 페이지로 이동</h1>
<hr>
${userName}

</body>
</html>

 

main.jsp는 데이터를 반드시 필요로 하고, 이를 ViewResolver가 찾아준다. 

이때 ds-servlet.xml에서 property name="prefix" 의 값을 기존에는 value="./" 로 넣어줬는데,

이를 value="/WEB-INF/views/" 로 수정한다.

 

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="viewResolver">
		<property name="prefix" value="/WEB-INF/views/" /> <!-- String 타입이기 때문에 value, 데이터가 있는 것으로 WEB-INF 하위에 있어서 경로 적어줌.-->
		<property name="suffix" value=".jsp" />
</bean>

 

이렇게 수정하게 되면 한 가지 문제가 생기는데,

xxxController에서 viewName이 붙지 않아도 되는 경우가 생기게 된다.

 

 

// LoginController

package com.koreait.app.view.member;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import com.koreait.app.biz.member.MemberDAO;
import com.koreait.app.biz.member.MemberDTO;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;


public class LoginController implements Controller {
	
	@Autowired 
	private MemberDAO memberDAO;

	@Override // 엠에이브이 (ModelAndView)
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
		// 1. 사용자(클라이언트, 브라우저)가 보낸 파라미터에서 값 추출
				String mid=request.getParameter("mid");
				String password = request.getParameter("password");
				
				// 2. DB 연동
				MemberDTO memberDTO=new MemberDTO();
				memberDTO.setMid(mid);
				memberDTO.setPassword(password);
				memberDTO = memberDAO.selectOne(memberDTO);
				
				// 3. 페이지 이동 == 네비게이션
				// 페이지 이동을 할 때 >> VeiwResolver가 .jsp를 해주기 때문에 jsp붙이지 않아도 됨. (c->v 는 .jsp 생략)
				// 다른 Action으로 보낼 때에는 .do (c -> c 는 .do가 여전히 있어야 함. (FC를 찾아가야 하기 때문에))
				// String path="login";
				
				ModelAndView mav = new ModelAndView();
				mav.setViewName("redirect:login.jsp"); // ViewResolver 도움이 필요하지 않은 경우 전체 경로를 작성해준다.

				if(memberDTO.getName() != null) {
					mav.addObject("userName", memberDTO.getName());
					mav.setViewName("main");
				}
				
				System.out.println("mav 로그 : " + mav);
				return mav;
	}


}

ViewResolver 도움이 필요 없거나, 리다이렉트를 써야 할 경우에는

mav.setViewName에 전체 경로를 써준다

>> mav.setViewName("redirect:login.jsp");

 

viewResolver는 default 포워드 방식임을 알 수 있다.

 

만약 여기서 WEB-INF 하위로 안 갈 거고, 포워드 방식으로 위와 같이 쓰고 싶다면?

>> 로직이 잘못됐다고 볼 수 있다. 

그 이유는 이러한 방식을 사용하면 보내야 할 데이터가 있는 경우 무조건 WEB-INF 하위로 들어가게 된다.

또한 보낼 데이터가 있다면 포워드를 써야 하니까 Resolver를 써야 한다.

(데이터가 있다면 안전하게 보내기 위해 Resolver 사용함)

 

 


 

Spring의 흐름 정리

먼저 jsp 동작을 시키면 톰캣이 구동하고, 컨테이너니까 web.xml이 돌아간다.

Spring에서 제공하는 DS를 사용하니까 web.xml에 작성한 xml 객체가 필요하게 되고,

그 xml 파일을 추가하게 되면 Spring 컨테이너가 개입을 한다.

이곳에서는 POJO를 다루고 

HandleMapping과 ViewResolver를 DI 하고,

핸들러 주입을 하는 경우 login 객체를 new 해주게 된다.

loginController는 @Autowired가 들어있어서 해당 범위가 스캔 범위에 들어가게 되고,

DAO도 메모리에 있어야 하므로 DAO 또한 스캔 범위에 들어간다.