JSP in Model2(MVC)

DobbyisCoding·2021년 1월 3일
2

intro

이전 포스트에서 MV, Model1을 포스팅 했지만 이번 포스트에서는 Model2(MVC)에 대해 포스팅 하려 한다.
Model1과 Model2의 가장 큰 차이점은 컨트롤러의 유무이다.
먼저 간단히 Model1에 대해 이야기 하면,

Model1은 클라이언트에게 JSP 페이지의 화면을 보여주고,
클라이언트가 요청을 하면 JSP 페이지에서 직접 로직을 수행하여 요청 처리를 하게 된다.

Model1으로 개발을 할 경우 개발 시간이 짧고 개발 비용이 적게 들지만 개발이 마무리되고 난 후 유지 보수를 하게 될 경우 코드 분석이 어려워 유지 보수 비용이 개발비용 보다 더 많이 들게 되는 단점이 있다.

또한 디자이너가 디자인을 변경해야 할 경우 태그 코드 외에 자바 코드들이 섞여 있기 때문에 많은 문제가 발생하게 된다.

이러한 단점들을 보완하기 위해 만들어진 것이 MVC 패턴을 이용한 Model 2이다.

Model2 (MVC)

MVC란 Model, View, Controller의 약자이다.

Model(POJO) 은 데이터 베이스와 연동하여 클라이언트의 요청을 처리해 주는 로직 부분이며
View(JSP)는 클라이언트에게 보여질 디자인페이지,
Controller(Servlet)는 이 두 부분을 연결해 주는 역할을 한다.


이렇게 Model2로 개발을 진행하게 되면 유지 보수 측면에서 디자인을 수정할 때는 View 페이지만 수정하면 되고 로직을 수정해야 한다면 Model 페이지만 확인하면 될 것이다.

Model2로 개발하게 되면 위의 Model1 흐름도와 비교해 봐도 초기 설계 단계에서 Model1보다 많은 시간을 소모하게 되고 구성이 조금 더 복잡하다는 것이 단점이 있다.

그러나 프로젝트의 규모가 크면 클수록 Model2로 개발하는 것이 생산성 측면으로도 Model1보다 훨씬 뛰어나다.

Why?

Model2로 개발하게 되면 디자이너들은 View 페이지만, 백 앤드 개발자는 Model 부분만 개발하는 등 분업하여 작업을 할 수 있기 때문에 일정한 규모 이상인 프로젝트는 대부분 Model2를 이용한다.

Model(POJO)
Model은 MVC 패턴에서 비즈니스 로직을 실행하는 부분이다.
MVC 패턴 안에서는 View가 JSP 디자인 코드를 모두 담당하기 때문에 Model에는 자바 코드들로만 이루어져 있어 Plain Old Java Object 즉 POJO라고도 불린다.
Model 부분에서는 대부분이 데이터베이스와 연동하여 SQL를 처리해 주는 코드로 구성되어 있다.
예를 들어 JSP 게시판 만들기에서 사용하는 BoardDAO.java 등 클래스를 Model이라고 부를 수 있다.

View(JSP)
MVC 패턴에서 디자인 부분을 담당한다.

Controller(Servlet)
View와 Model을 이어주는 핵심 요소이다.
Controller는 Servlet(웹상에서 실행되는 자바 클래스 파일)으로 구성되어 있는데 그 이유는 View와 Model을 연동해 주는 역할을 하고 있기 때문에 JAVA 코드뿐만 아니라 JSP 코드도 사용해야 하기 때문이다.
이러한 웹과 연동하여 자바 코드를 사용할 수 있는 것이 Servlet이다.

Board Model

DTO 파일과 DAO 파일 생성

멤버 필드를 정한 후 DTO파일을 만들어 주고
DAO 파일을 생성해주는데 DAO는 Database의 data에 access하는 트랜잭션 객체이다. 일종의 객체라는 것을 잊지말도록 하자. DAO는 저수준의 Logic과 고급 비지니스 Logic을 분리하고, domain logic으로부터 persistence mechanism을 숨기기 위해 사용한다. (적절히 디자인을 하면 모든 domain logic을 바꾸는 대신에 DAO를 바꾸기만 하면 된다.)
persistence 계층 : Database(영구 저장소)에 data를 CRUD하는 계층
// Create , Read , Update , Drop의 줄임말

DAO와 DTO 파일을 생성하고 보안성을 위한 SQL문을 파이널 변수로 지정한 SQL 파일을 만들어 주었다.

위의 DAO파일에서 상수인 LIST, INSERT등 변수 명으로만 사용 할 수 있는 방법은 import static 문이 있다.
식>import static java.lang.Integer.*; //DAO파일에 import 구문을 추가 해준다.
static 멤버 변수를 사용할 때 클래스 이름을 생략할 수 있게 해준다.

Controller가 직접 DAO파일에서 뽑아쓰지 않고 DAO에서 메소드를 호출할 Service 파일을 만들어 보안성을 높였고 한걸음 더 들어가면 확장성까지 갖출 수 있다. DAO 파일은 Service를 거쳐야만 사용할 수 있다.

Service파일에서 메소드를 호출할 때 마다 객체를 생성하지 않고 객체를 담은 instance 객체를 생성한다.

  • 위의 방법을 싱글톤 패턴(Singleton Pattern)이라 하며 애플리케이션이 시작될 때 어떤 클래스가 최초 한번만 메모리를 할당하고(Static) 그 메모리에 인스턴스를 만들어 사용하는 디자인패턴.

생성자가 여러 차례 호출되더라도 실제로 생성되는 객체는 하나고 최초 생성 이후에 호출된 생성자는 최초에 생성한 객체를 반환한다. (자바에선 생성자를 private로 선언해서 생성 불가하게 하고 getInstance()로 받아쓰기도 함)

장단점

장점 :

  • 고정된 메모리 영역을 얻으면서 한번의 new로 인스턴스를 사용하기 때문에 메모리 낭비를 방지할 수 있음

  • 또한 싱글톤으로 만들어진 클래스의 인스턴스는 전역 인스턴스이기 때문에 다른 클래스의 인스턴스들이 데이터를 공유하기 쉽다.

  • DBCP(DataBase Connection Pool)처럼 공통된 객체를 여러개 생성해서 사용해야하는 상황에서 많이 사용.

  • 두 번째 이용시부터는 객체 로딩 시간이 현저하게 줄어 성능이 좋아지는 장점!

단점 :

  • 싱글톤 인스턴스가 너무 많은 일을 하거나 많은 데이터를 공유시킬 경우 다른 클래스의 인스턴스들 간에 결합도가 높아져 "개방-폐쇄 원칙" 을 위배하게 된다. (=객체 지향 설계 원칙에 어긋남)
  • 따라서 수정이 어려워지고 테스트하기 어려워진다.

  • 또한 멀티쓰레드환경에서 동기화처리를 안하면 인스턴스가 두개가 생성된다든지 하는 경우가 발생할 수 있음

이렇게 Model 부분 파일의 생성을 끝으로 View와 Model의 중간에서 연결해 줄 Controller 파일을 생성한다.

제일 위의 사각형 안의 @WebServlet ("")은 어노테이션이라 하며 자바와 서블릿 내에서 사용하는데에 있어 용도의 차이점이 있다.
자바에서의 어노테이션은 컴파일이나 배포, 실행할 때 참조할 수 있는 아주 특별한 주석이다.
어노테이션을 사용하면 클래스나 필드, 메서드에 대해 부가 정보를 등록할 수 있다.
주석이므로 프로그램의 의미적인 부분에 직접 영향을 주지 않는다.
하지만 서블릿에서의 어노테이션은 web.xml에 배치정보를 등록한것과 동일한 URL로 출력하게 된다.
위의 이미지 처럼 web.xml에 서블릿과 서블릿 맵핑같은 배치 정보를 입력 하는 것을 서블릿에서 어노테이션을 사용하면 @WebServlet("/board/del.do")로 처리한 것과 같은 결과이기 때문에 서블릿에서의 어노테이션은 자바에서의 사용과 다르다.

Controller 파일의 어노테이션에서의 값은 기본 뷰로 디폴트 값으로 사용하고 뷰페이지에서 겟방식을 통해 파라미터 값을 가져와 그에 맞게 if~ else if문을 이용하여 요청에 맞는 메소드를 통해 Model의 서비스의 메소드의 실행을 할 수 있다.

처음 링크로 들어왔을 경우 디폴트 페이지를 보일 수 있도록
getParameter값이 null일 경우 list.jsp를 보여준다.
forward(request, response)메소드는 Web Container 차원에서 페이지 이동만 있다. 실제로 웹 브라우저는 다른 페이지로 이동했음을 알 수 없다. 그렇기 때문에 웹 브라우저에는 최초에 호출한 URL이 표시되고 이동한 페이지의 URL 정보는 볼 수 없다. 동일한 웹 컨테이너에 있는 페이지로만 이동할 수 있다. 현재 실행중인 페이지와 Forwad에 의해 호출될 페이지는 request와 response 객체를 공유한다.

그리고 list.jsp 초기 뷰 페이지에서
이미지와 같이 board.do?m='param'을 통해 service 메소드에서 if~ else if문을 통해 그에 맞는 요청에 대한 메소드를 실행 할 수 있다.
그리고 m값외에 추가 값을 가져올 때는 & 사용한다.


input메소드의 경우 sendRedirect() 메소드를 사용했는데 Redirect는 Web Container가 Redirect 명령이 들어오면 웹 브라우저에게 다른 페이지로 이동하라고 명령을 내린다. 그러면 웹 브라우저는 URL을 지시된 주소로 바꾸고 그 주소로 이동한다. 다른 웹 컨테이너에 있는 주소로 이동이 가능하다. 새로운 페이지에서는 request와 response객체가 새롭게 생성된다.
쉽게 생각해 fowardresponse의 차이점은 reqest와 response 객체를 공유하느냐 새로 생성을 하느냐의 차이라고 보면 된다.


위의 content 메소드에서는 BoardService의 객체를 service라는 BoardService타입의 변수에 담아주고 그 클래스가 가지고 있는 메소드를 이용해 contentS의 파라미터에 view페이지에서 넘겨 받은 seq 값 넣어 반환된 Board클래스 객체를 같은 타입의 dto 변수에 답고 setAttrribute를 이용했다. 그리고 forward 변수를 이용해 request와 response를 공유하고 content.jsp로 view 페이지의 이동을 한다.
그러면 content의 content.jsp의 view 페이지에서

(데이터 원형의 타입)request.getAttribute(객체명)을 이용해 Controller에서 보낸 객체를 뽑아 새로운 변수에 넣어 해당 페이지에서 사용이 가능하다.

  • ServletRequest 객체는 JSP/Servlet에서 클라이언트로부터의 요청이 왔을때 그 요청 정보를 객체화한것이다. HTTP 환경에서 클라이언트인 브라우저가 톰캣같은 서블릿 컨테이너로 요청을 보낼때마다 ServletRequest의 하위객체인 HttpServletRequest 객체가 하나씩 생성되며, 컨테이너에서 요청을 처리한 후 응답을 보낼때 사라지게 된다.

  • ServletRequest에는 객체를 저장하고 꺼내어 쓸 수 있는데, 저장할 때는 setAttribute("객체명",객체) 메서드를 사용하며, 꺼낼때는 getAttribute("객체명") 메소드를 사용한다. 앞서 말했듯 ServletRequest는 요청을 처리하고 나면 소멸되기 때문에 attribute와 관련된 메소드를 통해 하나의 요청이 처리되는 범위 안에서 데이터를 공유할 수 있다.

profile
Keep going

1개의 댓글

comment-user-thumbnail
2021년 1월 4일

정리 정말 잘해놓으셨네요! 어려운 내용인데 잘 보고 갑니다!!

답글 달기