※ 본 내용은 구멍가게 코딩단의 "코드로 배우는 스프링 웹 프로젝트"라는 책의 내용을 공부하다가 정리하게 된 내용이다.
Spring MVC의 동작 구조, 동작 흐름을 파악하는 것이 그렇게 간단하지가 않다.
게시판 관련 작업을 한다고 할때 다음과 같은 클래스들이 있다고 가정해 보자.
BoardDAO : interface로 MyBatis XML Mapper를 활용하여 DB 연동 작업
BoardDAOImpl : BoardDAO interface를 구현한 클래스
BoardController : @RequestMapping 어노테이션을 활용하여 HTTP URL과 jsp 뷰단을 mapping(연결)하는 역할
이상과 같을 때 게시물에 대한 페이징 처리를 위해 Criteria라는 클래스가 있다고 하자.
public class Criteria
{
private int myPage; //MySQL limit 구문에서 시작 페이지로 지정할 변수
private int perPageNum; //한 페이지당 보여질 게시물 갯수
public int getMyPage() { //myPage에 대한 getter
... 생 략 ...
}
public void setMyPage(int myPage) { //myPage에 대한 setter
... 생 략 ...
}
... 이하 생략 ...
}
이 클래스는 전체 게시물을 하나의 페이지당 몇 개씩 보여줄 것인지의 정보와 전체 페이지들 중에서 몇 번째 페이지의 게시물을 가져올 것인지에 대한 정보를 관리하는 역할하는 클래스이다.
이를 때에 BoardController에 아래와 같은 페이징 처리하는 메소드가 있다고 가정하자.
@Controller
@RequestMapping("/board/*")
public class BoardController
{
private static final Logger logger = LoggerFactory.getLogger(BoardController.class);
... 중략 ...
@RequestMapping(value = "/listCri", method=RequestMethod.GET)
public void listAll(Criteria cri, Model model) throws Exception
{
model.addAttribute("list", service.listCriteria(cri));
}
... 이하 생략 ...
}
이상의 상황에서 다음과 같은 url 접속이 있을 때 위의 각각의 클래스들이 어떻게 연결지어가면서 동작하는가 하는 것이다.
(아래에서 myPage와 perPageNum은 Criteria의 멤버 변수명과 일치해야 한다)
http://localhost:8080/board/listCri?myPage=3&perPageNum=15
와 같이 접속해 오면 @RequestMapping 어노테이션에 의해 BoardController의 다음 메소드가 실행이 될 것이다.
@RequestMapping(value = "/listCri", method=RequestMethod.GET)
public void listAll(Criteria cri, Model model) throws Exception
{
model.addAttribute("list", service.listCriteria(cri));
}
그리고 여기서 개발자의 손을 떠난 보이지 않는 영역가운데서 Spring에 의해서 모종의 동작들이 내부적으로 진행이 되는 것이다. 위의 listAll() 메소드에 개발자가 작성한 코드는 딸랑 한 줄 뿐이다. 이런 면이 편리하기도 하지만 내막을 모르면 개발자는 눈감고 더듬는 더듬이가 되는 것이다.
위의 메소드에서 내부적으로 Spring 프레임웤이 자동으로 Criteria 클래스의 객체를 생성하면서 http url에 있는 myPage, perPageNum의 값을 각각 Criteria의 두 멤버 변수의 getter, setter를 이용해서 값을 할당하게 된다.
그런 후에 model을 이용해서 jsp 단에 해당 값을 넘기고 @RequestMapping의 value에 지정한 값인 listCri라는 이름의 jsp인 listCri.jsp를 실행한다(이것 또한 명시적으로 return "listCri"라고 하지 않았지만 또 역시 내부적으로 Spring에 의해처 처리가 되는 영역이다).
그런데 여기서 Criteria의 멤버 변수 perPageNum을 pgNum으로 변경할 경우 다음과 같이 접속을 하면 어떻게 될까?
http://localhost:8080/board/listCri?myPage=3&pgNum=15
만일 멤버 변수만 perPageNum을 pgNum으로 변경했다면 위의 접속은 15페이지 값이 적용되지 않는다.
원리상 되야 될것 같은데 정상동작하지 않는다.
해법은 perPageNum에 맞게 명명된 getter와 setter를 pgNum에 맞게 변경해 주어야 한다. 이것까지 변경해 주어야 위의 url은 비로소 정상 동작을 하는 것이다.
pgNum에 대한 getter, setter 명명 규칙대로 변경하면 getter는 getPgNum()이 될 것이고 setter는 setPgNum()이 될 것이다.
이렇게 getter, setter 명명 규칙에 맞게 메소드 명을 변경하지 않으면(대소문자도 정확히) 아래 URL은 정상 동작을 기대하지 말아야 한다.
http://localhost:8080/board/listCri?myPage=3&pgNum=15
순수 Java/JSP로 개발할 때는 개발자가 직접 코딩해야 하던 것들이 Spring을 이용하면 개발자의 손 가락을 쉬게해 주는 여러 편리한 면도 있지만 이 편리함이라는 게 개발자의 손을 떠난 영역에서 동작하는 것들이 점점 많아 지게 된다는 이야기가 되고 개발자는 더듬이가 되어가야 한다는 이야기로 귀결하는 것 같다.
그래도 아무튼 뭐 어쩌겠는가?
'Spring MVC' 카테고리의 다른 글
전자정부프레임웤에서 컨트롤러 클래스 인식되게 하기 위한 환경설정법 (0) | 2019.05.08 |
---|---|
Instantiation of bean failed; Failed to instantiate [......]: Specified class is an interface 에러 문제 (0) | 2018.10.26 |
Spring(혹은 전자정부프레임워크)에서 DI(Dependency Injection 의존성 주입)에 대한 개념과 예제 코드 (0) | 2018.10.19 |
Spring MVC의 @ModelAttribute 어노테이션에 대한 개념 정리 (7) | 2018.07.24 |
Spring에서의 @RequestMapping 어노테이션에 대한 간단 정리 (0) | 2018.07.17 |