본문 바로가기
👨‍💻 2. 웹개발_Back end/2-6 Spring

[Spring] 6~7장 Spring MVC 적용 - .do 요청이 동작할 수 있도록HandlerMapping 적용하기 및 직접적인 JSP 호출 차단을 위한 ViewResolver 적용하기

by 달님🌙 2021. 10. 29.
반응형

 

실습 코드 참조

 

moonhy7/SpringFramework: Spring Framework 실습 코드 정리 (github.com)

 

GitHub - moonhy7/SpringFramework: Spring Framework 실습 코드 정리

Spring Framework 실습 코드 정리. Contribute to moonhy7/SpringFramework development by creating an account on GitHub.

github.com

 

 

6.1절 Spring MVC 적용 준비 ( _055_BoardWeb_Spring_MVC )

 

1) Controller 관련 파일 삭제

- Spring MVC를 적용하기에 앞서 직접 개발했던 Controller 관련 파일들은 모두 삭제한다.

- 삭제된 클래스들을 스프링에서 제공하는 클래스로 교체하면서 Spring MVC를 적용할 것이다.

- 첫 번째로 com.springbook.view.controller 패키지를 삭제한다.

 

2) String타입을 ModelAndView로 변경

- 그 후 기존에 사용하던 모든 Controller 클래스들은 스프링에서 제공하는 Contoller 인터페이스로 구현한다.

- 스프링에서 제공하는 Controller 인터페이스도 우리가 만들었던 Controller와 크게 다르지 않지만 handleRequest() 메소드의 리턴 타입이 String이 아닌 ModelAndView라는 점만 다르다.

 

 

6.2절 로그인 기능 구현

 

1. LoginController 구현

 

- 기존에 사용하던 LoginController 클래스에서 handleRequest() 메소드의 리턴 타입을 ModelAndView로 수정한다.

- 또한 화면 내비게이션에서 로그인 성공과 실패일 때 각 화면 정보를 ModelAndView 객체에 저장하여 리턴한다.

package com.springbook.view.user;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import com.springbook.biz.user.UserVO;
import com.springbook.biz.user.impl.UserDAO;

//SpringFramework에서 제공하는 Controller, interface의 handleRequest메소드는 리턴 타입 ModelAndView
public class LoginController implements Controller {
	@Override
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("로그인 처리");
		
		//1. 사용자 입력 정보 추출(login.jsp에서 전송한 id, password 받기)
		String id = request.getParameter("id");
		String password = request.getParameter("password");
		
		//2. DB연동 처리(UserDAO의 메소드 호출)
		UserVO vo = new UserVO();
		vo.setId(id);
		vo.setPassword(password);
		
		UserDAO userDAO = new UserDAO();
		UserVO user = userDAO.getUser(vo);
		
		//3. 화면 네비게이션(로그인 후 화면 이동 처리)
		//DB 연동 후 리턴받은 데이터와 View를 모두 담을 수 있는 객체
		ModelAndView mav = new ModelAndView();
		//로그인 성공 시 게시판 목록 조회 화면으로 이동
		if(user != null) {
			//redirect : viewResolver를 무시하고 바로 리다이렉트
			mav.setViewName("redirect:getBoardList.do");
		//로그인 실패 시 다시 로그인 화면으로 이동
		} else {
			mav.setViewName("redirect:login.jsp");
		}
		return mav;
	}
}

 

2. HandlerMapping 등록

 

- 작성된 LoginController가 클라이언트의 /login.do 요청에 대해서 동작하게 하려면 스프링 설정 파일인 presentation-layer.xml에 HandlerMapping과 LoginController를 <bean> 등록해야 한다.

- SimpleUrlHandlerMapping 객체는 Setter 인젝션을 통해 Properties 타입의 컬렉션 객체를 의존성 주입하고 있음

- 의존성 주입된 Properties 컬렉션에는 /login.do 경로 요청에 대해 아이디가 login인 객체가 매핑되어 있다.

- LoginController 클래스를 <bean> 등록할 때 반드시 SimpleUrlHandlerMapping에서 /login.do 키 값으로 매핑한 값과 같은 아이디로 등록해야 함

	<!-- HandlerMapping 등록 -->
	<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
		<property name="mappings">
			<props>
				<prop key="/login.do">login</prop>
			</props>
		</property>
	</bean>
	
	<!-- Controller 등록 -->
	<bean id="login" class="com.springbook.view.user.LoginController"></bean>

 

 

 

6.3절 글 목록 검색 기능 구현

 

1. GetBoardListController 구현

 

- 검색 결과를 세션이 아닌 ModelAndView 객체에 저장하고 있다.

- 세션은 클라이언트 부라우저 하나당 하나씩 서버 메모리에 생성되어 서버에 부담을 준다.

- 그래서 검색 결과를 세션이 아닌 HttpServletRequest 객체에 저장하는 것이 낫다.

- 하지만 GetBoardListController는 검색 결과를 HttpSession도 아니고 HttpServletRequest도 아닌 ModelAndView에 저장하고 있다.

- DispatcherServlet은 Controller가 리턴한 ModelAndView 객체에서 Model 정보를 추출한 다음 HttpServletRequest 객체에 검색 결과에 해당하는 Model 정보를 저장하여 JSP로 포워딩함

package com.springbook.view.board;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import com.springbook.biz.board.BoardVO;
import com.springbook.biz.board.impl.BoardDAO;

public class GetBoardListController implements Controller {
	@Override
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("글 목록 검색 처리");
		
		//1. 사용자 입력정보 추출(검색기능 나중에 구현)
		//2. DB 연동 처리(BoardDAO의 메소드 호출)
		BoardVO vo = new BoardVO();
		BoardDAO boardDAO = new BoardDAO();
		List<BoardVO> boardList = boardDAO.getBoardList(vo);
		
		//3. 검색 결과를 세션에 저장하고 목록 화면으로 이동한다.
		ModelAndView mav = new ModelAndView();
		//ModelAndView 객체에 데이터 담기
		mav.addObject("boardList", boardList);
		//ModelAndView 객체에 View 담기
		mav.setViewName("getBoardList");
		return mav;
	}
}

 

2. HandlerMapping 등록

 

- GetBoardListController 객체가 /getBoardList.do 요청에 동작할 수 있도록 SimpleUrlHandlerMapping에 매핑 정보 추가

 

3. 게시글 목록 검색 과정

① 클라이언트로부터 /getBoardList.do 요청을 전송하면 DispatcherServlet이 요청을 받고

② SimpleUrlHAndlerMapping을 통해 요청을 처리할 GetBoardListController를 검색한다.

③ DispatcherServlet은 검색된 GetBoardListController를 실행하여 요청을 처리한다.

④ GetBoardListController는 검색 결과인 List<BoardVO>와 getBoardList.jsp 이름을 ModelAndView 객체에 저장하여 리턴한다.

⑤ DispatcherServlet은 ModelAndView로부터 View 정보를 추출하고 ViewResolver를 이용하여 응답으로 사용할 getBoardList.jsp를 검색한다. 

⑥ DispatcherServlet은 getBoardList.jsp를 실행하여 글 목록 화면을 전송한다.

 

 

6.4절 글 상세 조회 기능 구현

 

1. GetBoardController 구현

 

- GetBoardController는 GetBoardListController와 기능이 같다.

- 따라서 검색 결과로 얻어낸 Model과 View 정보를 ModelAndView 객체에 저장하여 리턴하도록 구현한다

package com.springbook.view.board;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import com.springbook.biz.board.BoardVO;
import com.springbook.biz.board.impl.BoardDAO;

public class GetBoardController implements Controller {
	@Override
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("글 상세 조회 처리");
		
		//1. 상세 조회할 게시글 번호 추출
		String seq = request.getParameter("seq");

		//2. DB 연동 처리(BoardDAO의 메소드 호출)
		BoardVO vo = new BoardVO();
		vo.setSeq(Integer.parseInt(seq));
		
		BoardDAO boardDAO = new BoardDAO();
		BoardVO board = boardDAO.getBoard(vo);
		
		//3. 검색 결과를 세션에 저장하고 목록 화면으로 이동한다.
		ModelAndView mav = new ModelAndView();
		mav.addObject("board", board);	//Model 정보 저장
		mav.setViewName("getBoard");	//View 정보 저장
		return mav;
	}
}

 

2. HandlerMapping 등록

 

- GetBoardController 객체가 /getBoard.do 요청에 동작할 수 있도록 SimpleUrlHAndlerMapping에 매핑 정보를 추가한다.

 

3. 실행 화면

 

 

6.5절 글 등록 기능 구현하기

 

1. InsertBoardController 구현

 

- 글 등록 기능을 처리하고 나면 반드시 ModelAndView 객체를 리턴해야 한다.

- 따라서 글 등록 후 글 목록 화면으로 이동하기 위해 ModelAndView 객체에 getBoardList.do를 View 이름으로 설정하고 리턴한다.

- 그리고 사용자가 입력한 한글은 web.xml 파일에 ChararcterEncodingFilter가 등록되었으므로 깨지지 않고 잘 처리된다.

package com.springbook.view.board;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import com.springbook.biz.board.BoardVO;
import com.springbook.biz.board.impl.BoardDAO;

public class InsertBoardController implements Controller {
 @Override 
 public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) {
	 System.out.println("글 등록 처리");
		
		//1. 사용자 입력정보 추출(insertBoard.jsp에서 전송된 정보 추출)
		String title = request.getParameter("title");
		String writer = request.getParameter("writer");
		String content = request.getParameter("content");
		
		//2. DB 연동 처리(BoardDAO의 메소드 호출)
		BoardVO vo = new BoardVO();
		vo.setTitle(title);
		vo.setWriter(writer);
		vo.setContent(content);
		
		BoardDAO boardDAO = new BoardDAO();
		boardDAO.insertBoard(vo);
		
		//3. 화면 네비게이션
		//글 등록 처리 후 글 목록 페이지로 이동
		ModelAndView mav = new ModelAndView();
		mav.setViewName("redirect:getBoardList.do");
		return mav;
 }
}

 

2. HandlerMapping 등록

 

- InsertBoardController가 /getBoard.do 요청에 동작할 수 있도록 SimpleUrlHAndlerMapping에 매핑 정보를 추가한다.

- 이후에 추가될 글 수정, 글 삭제, 로그아웃 관련 설정도 함께 처리한다.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

	<!-- HandlerMapping 등록 -->
	<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
		<property name="mappings">
			<props>
				<prop key="/login.do">login</prop>
				<prop key="/getBoardList.do">getBoardList</prop>
				<prop key="/getBoard.do">getBoard</prop>
				<prop key="/insertBoard.do">insertBoard</prop>
				<prop key="/updateBoard.do">updateBoard</prop>
				<prop key="/deleteBoard.do">deleteBoard</prop>
				<prop key="/logout.do">logout</prop>
			</props>
		</property>
	</bean>
	
	<!-- Controller 등록 -->
	<bean id="login" class="com.springbook.view.user.LoginController"></bean>
	<bean id="getBoardList" class="com.springbook.view.board.GetBoardListController"></bean>
	<bean id="getBoard" class="com.springbook.view.board.GetBoardController"></bean>
	<bean id="insertBoard" class="com.springbook.view.board.InsertBoardController"></bean>
	<bean id="updateBoard" class="com.springbook.view.board.UpdateBoardController"></bean>
	<bean id="deleteBoard" class="com.springbook.view.board.DeleteBoardController"></bean>
	<bean id="logout" class="com.springbook.view.user.LogoutController"></bean>
</beans>

 

 

6.6절 글 수정 기능 구현하기

 

1. UpdateBoardController 구현

 

package com.springbook.view.board;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import com.springbook.biz.board.BoardVO;
import com.springbook.biz.board.impl.BoardDAO;

public class UpdateBoardController implements Controller {
	@Override
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("글 수정 처리");
		
		//1. 사용자 입력정보 추출(getBoard.jsp에서 전송된 정보 추출)
		String seq = request.getParameter("seq");
		String title = request.getParameter("title");
		String content = request.getParameter("content");
		
		//2. DB 연동 처리(BoardDAO의 메소드 호출)
		BoardVO vo = new BoardVO();
		vo.setSeq(Integer.parseInt(seq));
		vo.setTitle(title);
		vo.setContent(content);
		
		BoardDAO boardDAO = new BoardDAO();
		boardDAO.updateBoard(vo);
		
		//3. 화면 네비게이션
		//수정처리 후 글 목록 화면으로 이동
		ModelAndView mav = new ModelAndView();
		mav.setViewName("redirect:getBoardList.do");
		return mav;
	}
}

 

 

6.7절 글 삭제 기능 구현하기

 

1. DeleteBoardController 구현

 

package com.springbook.view.board;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import com.springbook.biz.board.BoardVO;
import com.springbook.biz.board.impl.BoardDAO;

public class DeleteBoardController implements Controller {
	@Override
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("글 삭제 처리");
		
		//1.사용자 입력정보 추출(getBoard.jsp에서 전송된 정보 추출)
		String seq = request.getParameter("seq");

		//2. DB 연동 처리(BoardDAO의 메소드 호출)
		BoardVO vo = new BoardVO();
		vo.setSeq(Integer.parseInt(seq));
		
		BoardDAO boardDAO = new BoardDAO();
		boardDAO.deleteBoard(vo);
		
		//3. 화면 네비게이션
		//글 삭제 처리 후 글 목록 화면으로 이동
		ModelAndView mav = new ModelAndView();
		mav.setViewName("redirect:getBoardList.do");
		return mav;
	}
}

 

 

6.8절 로그아웃 기능 구현하기

 

1. LogoutController 구현

 

package com.springbook.view.user;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;


public class LogoutController implements Controller {
	@Override
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) {
		System.out.println("로그아웃 처리");
		
		//1. 브라우저와 연결된 세션 객체를 강제 종료한다.
		HttpSession session = request.getSession();
		session.invalidate();

		//2. 세션 종료 후, 로그인 화면으로 이동
		ModelAndView mav = new ModelAndView();
		mav.setViewName("redirect:login.jsp");
		return mav;
	}
}

 

 

6.9절 ViewResolver 활용하기

 

1. ViewResolver 적용하는 이유

 

- ViewResolver는 아직 스프링 설정 파일에 적용하지 않은 요소이다.

- ViewResolver를 이용하면 클라이언트로부터의 직접적인 JSP 호출을 차단할 수 있어 대부분의 웹 프로젝트에서 ViewResolver 사용은 거의 필수이다.

- ViewResolver는 JSP를 View로 사용하는 경우에는 InternalResourceViewResolver를 사용한다.

- getBoardList.jsp 파일을 브라우저에서 직접 호출하면 아래와 같이 아무 데이터도 출력되지 않는다.

- 게시글 목록을 검색하는 GetBoardListController가 실행되지 않았기 때문이다.

- GetBoardListController부터 실행될 수 있도록 적절히 제어하는 역할을 ViewResolver가 해준다.

 

2. ViewResolver 적용하기

 

- WEB-INF 폴더는 절대 브라우저에서 접근할 수 없으므로 WEB-INF 폴더로 이동한 JSP 파일들은 절대 클라이언트 브라우저에서 접근할 수 없다.

 

- 하지만 InternalResourceViewResolver를 아래와 같이 설정하면 WEB-INF 폴더에 있는 JSP 파일을 View 화면으로 사용할 수 있음

- 결과적으로 직접적인 JSP 호출을 차단하게 된다.

	<!-- ViewResolver 등록 -->
	<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/board/"></property>
		<property name="suffix" value=".jsp"></property>
	</bean>

 

 

3. Controller 수정

 

1) LoginController

- ViewResolver를 적용했을 때 ModelAndView 객체에 저장되는 View 이름은 ViewResolver 설정을 고려하여 등록한다.

- 로그인에 성공하거나 실패했을 떄 View 이름 앞에 redirect:을 붙여서 ViewResolver가 설정되더라도 이를 무시하고 리다이렉트하도록 한다.

//3. 화면 네비게이션(로그인 후 화면 이동 처리)
		//DB 연동 후 리턴받은 데이터와 View를 모두 담을 수 있는 객체
		ModelAndView mav = new ModelAndView();
		//로그인 성공 시 게시판 목록 조회 화면으로 이동
		if(user != null) {
			//redirect : viewResolver를 무시하고 바로 리다이렉트
			mav.setViewName("redirect:getBoardList.do");
		//로그인 실패 시 다시 로그인 화면으로 이동
		} else {
			mav.setViewName("redirect:login.jsp");
		}
		return mav;
	}
}

 

2) GetBoardListController

- GetBoardListController에서 확장자 .jsp를 생략하여 접두사와 접미사를 할당하여 파일을 실행한다.

//3. 검색 결과를 세션에 저장하고 목록 화면으로 이동한다.
		ModelAndView mav = new ModelAndView();
		//ModelAndView 객체에 데이터 담기
		mav.addObject("boardList", boardList);
		//ModelAndView 객체에 View 담기
		mav.setViewName("getBoardList");
		return mav;

 

3) 그 외 컨트롤러들 

- Insert, Update, Delete 컨트롤러 클래스에 모두 redirect:getBoard.do를 View 이름으로 설정한다.

//3. 화면 네비게이션
ModelAndView mav = new ModelAndView();
mav.setViewName("redirect:getBoardList.do");
return mav;

 

4) LogoutController

- 로그아웃 처리 후 로그인 화면으로 이동할 수 있도록 login.jsp 화면으로 넘긴다.

//2. 세션 종료 후, 로그인 화면으로 이동
ModelAndView mav = new ModelAndView();
mav.setViewName("redirect:login.jsp");
return mav;

 

 

반응형

댓글