17.1 웹 애플리케이션 모델
- 웹 애플리케이션을 개발할 때 일일이 처음부터 새로 개발하는 것이 아니라 기존에 웹 애플리케이션 개발 방법이나 방식을 따름
- 따라서 지금의 웹 애플리케이션 개발은 표준화 소스 구조(=웹 애플리케이션 모델)를 만들어 진행
- 웹 애플리케이션 모델의 종류에는 모델1과 모델2 방식이 있음
<모델1 방식>
- 비즈니스 로직 작업(ex. db연동)과 그 작업 결과를 나타내주는 작업을 동일한 JSP에서 수행(앞서 했던 실습들)
- 모든 클라이언트의 요청과 비즈니스 로직 처리를 JSP가 담당
- 유지보수가 어려움, 코드 재사용성이 떨어짐
<모델2 방식>
- 웹 애플리케이션의 각 기능(클라이언트의 요청 처리, 응답 처리, 비즈니스 로직 처리)을 분리해서 구현
- 각 기능이 서로 분리되어 있어 개발 및 유지보수가 쉽고 각 기능(모듈)의 재사용성이 높음
- 현재 모든 웹 프로그램은 모델2 방식으로 개발함
17.2 MVC 디자인 패턴
- 모델2 구조에는 여러 가지 개념들이 사용되는데 그 중 가장 자주 사용되는 개념이 MVC
- MVC : Model-View-Controller(모델-뷰-컨트롤러)
(: 일반 pc프로그램 개발에 사용되는 디자인 패턴을 웹 애플리케이션에 도입한 것)
- 모델2 방식으로 구현한다는 말은 곧 MVC로로 구현한다는 것과 같은 의미
- Controller : 사용자의 요청을 받아 어떤 비즈니스 로직을 처리해야 할지 제어
- 서블릿이 담당
- 요청에 대해서 필요한 모델을 호출
- 모델에서 처리한 결과를 보여주기 위해 JSP를 선택
- Model : 비즈니스 로직을 처리(ex. db연동)
- 일반적으로 DAO와 VO 클래스로 이루어짐
- View : 사용자에게 보여줄 화면을 담당, 모델에서 처리한 결과를 화면에 구현
- JSP가 화면 기능을 담당
- 모델에서 처리한 결과를 화면에 표시
17.3 MVC를 이용한 회원 관리
- 앞서 했던 회원 관리 기능을 MVC 방식으로 구현해보자!
- 서블릿 : 브라우저 요청 / 모델(DAO) : 비즈니스 처리 / JSP : 화면
회원 정보 조회
- 과정
- 브라우저에서 /mem.do로 요청
- 서블릿(Controller)가 요청을 받아 MemberDAO의 listMembers() 메서드 호출
- MemberDAO의 listMembers() 메서드에서 SQL 문으로 회원 정보를 조회한 후 회원 정보를 MemberVO에 설정하여 반환
- 다시 MemberController에서 조회한 회원 정보를 회원 목록창(listMembers.jsp)으로 포워딩
- 회원 목록창(listMembers.jsp)에서 포워딩한 회원 정보를 목록으로 출력
- memberController.java
...
List members=dao.listMember();
request.setAttribute("members", members);
RequestDispatcher dispatcher=request.getRequestDispatcher("test01/listMembers.jsp");
dispatcher.forward(request, response);
- listMembers.jsp
...
<c:choose>
<c:when test= "${empty members }">
<tr>
<td colspan=5 align="center">
<b>등록된 회원이 없습니다.</b>
</td>
</tr>
</c:when>
<c:otherwise>
<c:forEach var="mem" items="${members }">
<tr align="center">
<td>${mem.id }</td>
<td>${mem.pwd }</td>
<td>${mem.name}</td>
<td>${mem.email }</td>
<td>${mem.joinDate}</td>
</tr>
</c:forEach>
</c:otherwise>
</c:choose>
...
- 바인딩한 속성은 표현언어로 바로 접근하면 됨!
회원 정보 추가
- 요청사항이 많아졌기 때문에 컨트롤러가 브라우저로부터 어떤 요청을 받았는지 알아내서 그 요청에 대해 해당하는 모델을 선택하여 작업을 요청 함 >> 커맨드 방법
- 커맨드 패턴 : 브라우저가 URL 패턴을 이용해 컨트롤러에게 수행 작업을 요청하는 방법
- 컨트롤러는 HttpServletRequest의 getPathInfo() 메서드를 이용해 URL 패턴에서 요청명을 받아와 작업을 수행
- 요청형식 : http://localhost:8090/pro17/member/listMembers.do
>> /member : 첫번째 단계의 요청, 회원 기능을 의미, /listMembers.do : 두 번째 요청, 회원 조회 기능을 의미
- 회원 가입 과정
- 브라우저에서 회원가입하기 버튼을 누르면 ~/member/memberForm.do로 요청
- MemberController에서 getPathInfo()를 통해 요청명(memberForm.do)를 받아와 /test02/memberForm.jsp(회원 가입창)로 dispatch
- 회원 가입창에서 회원 정보를 입력하고 URL 패턴을 /member/addMember.do로 서버에 요청
- MemberController에서 getPathInfo()를 통해 요청명(addMember.do)를 받아옴
- 요청명에 대해 MemberDAO의 addMember()메서드 호출
- addMember() 메서드에서 SQL문으로 테이블에 회원 정보를 추가
회원 정보 수정/삭제
- MemberController.java
else if (action.equals("/addMember.do")) {
String id = request.getParameter("id");
String pwd = request.getParameter("pwd");
String name = request.getParameter("name");
String email = request.getParameter("email");
MemberVO memberVO = new MemberVO(id, pwd, name, email);
memberDAO.addMember(memberVO);
request.setAttribute("msg", "added");
nextPage = "/member/listMembers.do";
}
else if (action.equals("/memberForm.do")) {
nextPage = "/test03/memberForm.jsp";
}
else if(action.equals("/modMemberForm.do")){
String id=request.getParameter("id");
MemberVO memInfo = memberDAO.findMember(id);
request.setAttribute("memInfo", memInfo);
nextPage="/test03/modMemberForm.jsp";
}
else if(action.equals("/modMember.do")){
String id=request.getParameter("id");
String pwd=request.getParameter("pwd");
String name= request.getParameter("name");
String email= request.getParameter("email");
MemberVO memberVO = new MemberVO(id, pwd, name, email);
memberDAO.modMember(memberVO);
request.setAttribute("msg", "updated");
nextPage="/member/listMembers.do";
}
else if(action.equals("/delMember.do")){
String id=request.getParameter("id");
memberDAO.delMember(id);
request.setAttribute("msg", "deleted");
nextPage="/member/listMembers.do";
}
- MemberDAO.java
public MemberVO findMember(String id) {
MemberVO memInfo=null;
try {
con=dataFactory.getConnection();
String query="select * from t_member where id=?";
pstmt=con.prepareStatement(query);
pstmt.setString(1, id);
ResultSet rs=pstmt.executeQuery();
rs.next();
String name=rs.getString("name");
String pwd=rs.getString("pwd");
String email=rs.getString("email");
Date joinDate=rs.getDate("joinDate");
memInfo=new MemberVO(id,pwd,name,email,joinDate);
pstmt.close();
con.close();
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
return memInfo;
}
public void modMember(MemberVO memberVO) {
try {
con=dataFactory.getConnection();
String query="update t_member set pwd=?, name=?, email=? where id=?";
pstmt=con.prepareStatement(query);
pstmt.setString(1, memberVO.getPwd());
pstmt.setString(2, memberVO.getName());
pstmt.setString(3, memberVO.getEmail());
pstmt.setString(4, memberVO.getId());
pstmt.executeUpdate();
pstmt.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void delMember(String id) {
try {
con=dataFactory.getConnection();
String query="delete from t_member where id=?";
pstmt=con.prepareStatement(query);
pstmt.setString(1, id);
pstmt.executeUpdate();
pstmt.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
- modMemberForm.jsp
<form method="post" action="${contextPath }/member/modMember.do?id=${memInfo.id}">
<!-- 지금 id가 disabled되어 있어서 id는 전송이 안되므로 주소 뒤에 id를 꼭 붙여줘야 함 -->
<h1 style="text-align:center">회원 수정창</h1>
<table align="center">
<tr>
<td width="200"><p align="right">아이디</td>
<td width="400"><input type="text" name="id" value="${memInfo.id }" disabled></td>
</tr>
<tr>
<td width="200"><p align="right">비밀번호</td>
<td width="400"><input type="password" name="pwd" value="${memInfo.pwd }"></td>
</tr>
<tr>
<td width="200"><p align="right">이름</td>
<td width="400"><p><input type="text" name="name" value="${memInfo.name }"></td>
</tr>
<tr>
<td width="200"><p align="right">이메일</td>
<td width="400"><p><input type="text" name="email" value="${memInfo.email }"></td>
</tr>
<tr>
<td width="200"><p align="right">가입일</td>
<td width="400"><p><input type="text" name="joinDate" value="${memInfo.joinDate }" disabled></td>
</tr>
<tr>
'BackEnd > Spring' 카테고리의 다른 글
20장. 스프링 AOP 기능 (0) | 2022.02.28 |
---|---|
19장. 스프링 의존성 주입과 제어 역전 기능 (0) | 2022.02.27 |
18장. 스프링 프레임워크 시작하기 (0) | 2022.02.26 |
17장. 모델2 방식으로 효율적으로 개발하기 - ③ 답변형 게시판(답글쓰기, 페이징 구현) (2) | 2022.02.25 |
17장. 모델2 방식으로 효율적으로 개발하기 - ② 답변형 게시판(CRUD 구현) (0) | 2022.02.25 |
Comment