모도리는 공부중

21.03.09. SRPING - mvc패턴 마무리 및 전자정부프레임워크 시작 본문

K-디지털 빅데이터 분석서비스 개발자과정 20.11.02~21.04.12/JAVA

21.03.09. SRPING - mvc패턴 마무리 및 전자정부프레임워크 시작

공부하는 모도리 2021. 3. 9. 14:07
728x90
반응형

 

pageContext 객체를 이용하여 읽어오는 작업을 해보자.

 

memberList.jsp

<!-- 자바 코드 -->
<% String ctx = request.getContextPath(); %>
<!-- 스프링 코드 -->
<c:set var="ctx" value="${pageContext.request.contextPath}"/>

우리는 jsp에서 spring코드를 사용중이므로 자바코드는 삭제하고 function과 주소 연결부에서 ContextPath에 해당하는 /mvc를 ${ctx}로 변경해준다. 다른 파일도 열어가면서 contextpath를 기존 /mvc에서 ${ctx}로 수정해주도록 하자. 그리고 상단에 c:set 코드 말고 taglib가 빠졌다면 그것도 추가해준다.

 

<%@page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="ctx" value="${pageContext.request.contextPath}"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
  <script type="text/javascript">
  	function memberIn(){
  		location.href="${ctx}/memberRegister.do";
  	}
  	function memberDel(num){
  		location.href="${ctx}/memberDelete.do?num="+num; // 쿼리스트링 방식을 이용하여 num값이 주소에 get방식으로 붙어 넘어가도록 지정한다.
  	}
  </script>
</head>
<body>
<table class="table">
	<tr>
		<td>번호</td>
		<td>아이디</td>
		<td>비밀번호</td>
		<td>이름</td>
		<td>나이</td>
		<td>전화번호</td>
		<td>이메일</td>
		<td>삭제</td>
	</tr>
	<c:forEach var="vo" items="${list }">
		<tr>
			<td>${vo.num}</td>
			<td><a href="${ctx }/memberContent.do?num=${vo.num }">${vo.id}</a></td>
			<td>${vo.pass}</td>
			<td>${vo.name}</td>
			<td>${vo.age}</td>
			<td>${vo.phone}</td>
			<td>${vo.email}</td>
			<td><input type="button" value="삭제" class="btn btn-default" onclick="memberDel(${vo.num})"></td>
		</tr>
	</c:forEach>
	<tr>
		<td colspan="8" align="right">
			<input type="button" value="회원가입" class="btn btn-primary" onclick="memberIn()">
		</td>
	</tr>
</table>
</body>
</html>

memberContent.jsp

<%@ page language="java" contentType="text/html; charset=EUC-KR"
	pageEncoding="EUC-KR"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="ctx" value="${pageContext.request.contextPath}"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<title>Insert title here</title>
</head>
<body>
<form action="${ctx }/memberUpdate.do" method="post">
<input type="hidden" name="num" value="${vo.num }">
	<table class="table table-borderd" width: 628px">
		<colgroup>
			<col style="width: 105px">
			<col style="width: 523px">
		</colgroup>
		<thead>
			<tr>
				<th>번호</th>
				<th>${vo.num }</th>
			</tr>
		</thead>
		<tbody>
			<tr>
				<td>아이디</td>
				<td>${vo.id }</td>
			</tr>
			<tr>
				<td>비밀번호</td>
				<td>${vo.pass }</td>
			</tr>
			<tr>
				<td>이름</td>
				<td>${vo.name }</td>
			</tr>
			<tr>
				<td>나이</td>
				<td><input type="text" name="age" value="${vo.age }"></td>
			</tr>
			<tr>
				<td>전화번호</td>
				<td><input type="text" name="phone" value="${vo.phone }"></td>
			</tr>
			<tr>
				<td>이메일</td>
				<td><input type="text" name="email" value="${vo.email }"></td>
			</tr>
			<tr>
				<td colspan="2" align="center">
					<input type="submit" value="수정하기 " class="btn btn-default">
					<input type="reset" value="취소" class="btn btn-default">
					<input type="button" value="리스트" class="btn btn-success" onclick="location.href='${ctx }/memberList.do'">
				</td>
			</tr>
		</tbody>
	</table>
</form>
</body>
</html>

memberRegister.jsp

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="ctx" value="${pageContext.request.contextPath}"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet"
	href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script
	src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script
	src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<title>Insert title here</title>
</head>
<body>
	<form action="${ctx}/memberInsert.do" method="post">
	<!-- /mvc 앞에는 항상 127.0.0.1:8081이 붙어있다는 전제가 있다. -->
	<!-- 많은 양의 데이터를 보낼 때는 post방식을 취한다. --> 
		<table class="table">
			<thead>
				<tr>
					<th class="tg-0pky">아이디</th>
					<th class="tg-0pky"><input type="text" name="id"></th>
				</tr>
			</thead>
			<tbody>
				<tr>
					<td class="tg-0pky">비밀번호</td>
					<td class="tg-0pky"><input type="password" name="pass"></td>
				</tr>
				<tr>
					<td class="tg-0pky">이름</td>
					<td class="tg-0pky"><input type="text" name="name"></td>
				</tr>
				<tr>
					<td class="tg-0pky">나이</td>
					<td class="tg-0pky"><input type="text" name="age"></td>
				</tr>
				<tr>
					<td class="tg-0pky">전화번호</td>
					<td class="tg-0pky"><input type="text" name="phone"></td>
				</tr>
				<tr>
					<td class="tg-0pky">이메일</td>
					<td class="tg-0pky"><input type="text" name="email"></td>
				</tr>
				<tr>
					<td class="tg-0pky" colspan="2" align="center">
						<input type="submit" value="가입" class="btn btn-primary" />
						<input type="reset" value="취소" class="btn btn-primary" />
					</td>
				</tr>
			</tbody>
		</table>
	</form>
</body>
</html>

 

memberFrontController로 와봅시다.

이 부분은 다른 컨트롤러에게 일을 시키는 부분이다. 하지만 지금 이 상태는 어떤 컨트롤러가 어떤 일을 하는지 만든 사람이 다 알고 있어야 한다. 유지보수하는 사람이 전부 기억하고 있기란 어렵다. 그리고 사람은 또 바뀔 수 있다..

 

위 사진에 있는 컨트롤러를 밖으로 뺄 것이다. kr.smhrd.frontcotroller 패키지에 HandlerMapping이라는 명의 클래스를 생성한다. 이 핸들러는 경로와 pojo를 연결시킬 것이다.

package kr.smhrd.frontcontroller;

import java.util.HashMap;

import kr.smhrd.controller.Controller;
import kr.smhrd.controller.MemberContentController;
import kr.smhrd.controller.MemberDeleteController;
import kr.smhrd.controller.MemberInsertController;
import kr.smhrd.controller.MemberListController;
import kr.smhrd.controller.MemberRegisterController;
import kr.smhrd.controller.MemberUpdateController;

public class HandlerMapping {

	private HashMap<String, Controller> mappings; // hashmap은 검색과 연관되어 있다.
	// <key, value> key는 문자열로 값이 들어가므로 String, value는 포조들의 부모인 Controller.
	public HandlerMapping() { // 이 객체가 만들어질 때
		mappings = new HashMap<String, Controller>();
		// xml
		// 키값이 들어오면, pojo를 연결해라.
		mappings.put("/memberList.do", new MemberListController());
		mappings.put("/memberInsert.do", new MemberInsertController());
		mappings.put("/memberRegister.do", new MemberRegisterController());
		mappings.put("/memberDelete.do", new MemberDeleteController());
		mappings.put("/memberContent.do", new MemberContentController());
		mappings.put("/memberUpdate.do", new MemberUpdateController());
	}
	public Controller getController(String url) { // 이 url 요청 들어오면 어떤 pojo가 일을 하는지 알려줄래?
		return mappings.get(url);	// 반환은 url 매핑된 컨트롤러.
	}
}
/*		HashMap으로 대체할 if ~ else 컨트롤러문.

		if (command.equals("/memberList.do")) {
//			MemberListController controller = new MemberListController(); ← 이것의 부모타입인 Controller를 상단에 미리 선언
			controller = new MemberListController();
			nextView = controller.requestHandler(request, response);
		} else if (command.equals("/memberInsert.do")) {
//			MemberInsertController controller = new MemberInsertController();
			controller = new MemberInsertController(); // 일할 알바생 controller 호출
			nextView = controller.requestHandler(request, response); // controller를 일하게 시키고 일이 끝나면 nextView로 값을 넘긴다.
		} else if (command.equals("/memberRegister.do")) {
			// memberRegister.html로 가라고 경로만 알려주면 된다. 다른 업무처리는 없음.
			controller = new MemberRegisterController();
			nextView = controller.requestHandler(request, response);
		} else if (command.equals("/memberDelete.do")) {
			// memberDelete를 대신 처리할 POJO 생성
			controller = new MemberDeleteController();
			nextView = controller.requestHandler(request, response);
		} else if (command.equals("/memberContent.do")) {
			// POJO 생성
			controller = new MemberContentController();
			nextView = controller.requestHandler(request, response);
		} else if (command.equals("/memberUpdate.do")) {
			// POJO 생성
			controller = new MemberUpdateController();
			nextView = controller.requestHandler(request, response);
		}

*/

스프링은 앞으로 외부 xml파일이 자주 등장하게 된다. 소스코드로 만들 수 없으면 xml로 만들어서 유지보수를 쉽게 할 수 있도록 만들어야하므로 현업에서 일을 하다보면 갈수록 소스코드를 건들이지 않는 방향으로 일을 많이 하게 된다. mvc도 마찬가지로 유지보수를 쉽게 하는 방향으로 계속 흘러갈 것이다.

 

Q. xml이 아닌 json으로 하면 안됩니까?

A. 가능할 것이다. xml이든 json이든 결국 핸들링을 하려면 api를 알아야 한다.

 

또는 properties 파일 형식으로도 만들 수 있다.

 

정리하자면 핸들링하는 방식은 1. xml, 2. json, 3. properties 형식 중 한 가지로 만들 수 있다.

위의 command는 임의로 만든 코드이다.

아무튼, hashmap으로 매핑해주었으니 이제 frontcontroller에게서 controller 관련 if문을 해방시켜줄 차례이다. 그리고 핸들러매핑을 연결해준다.

(if ~ else문 보고 방 빼라고 하자. 새로운 입주자가 생겼으니.)

		HandlerMapping mapping = new HandlerMapping();	// HandlerMapping 호출
		controller = mapping.getController(command);	// mapping에 command(ex:/memberList.do)를 넘긴다.
		nextView = controller.requestHandler(request, response);

그리고 또 방 빼라고 할 녀석이 있다. 굳이 안 만들어주어도 되지만 이왕 하는거 진도 빼봅시다. (인터넷에 viewResolver를 검색하면 해당 업무가 상세히 나와있을 것이다.)

 

kr.smhrd.frontcontroller 패키지에 ViewResolver라는 클래스를 생성한다.

package kr.smhrd.frontcontroller;

public class ViewResolver {
	// ViewResolver.makeURL() 로 호출할 수 있다.
	public static String makeURL(String url) {
		// 주소 수정할 일이 있으면 이제 frontcontroller를 만질게 아니고 이 파일에 있는 주소만 수정해주면 된다.
		return "/WEB-INF/view/"+url+".jsp";
	}
}

 

그리고 RequestDispatcher를 수정한다. return값과 같은 값이 있는 위치만 수정해주면 된다.

 else {
	// forward					// viewResolver : "/WEB-INF/view/"+nextView+".jsp"
	RequestDispatcher rd = request.getRequestDispatcher(ViewResolver.makeURL(nextView));
	rd.forward(request, response);
}

 

최종적으로 수정된 위치들을 확인하면 아래 그림의 위치와 같다.

코드는 다음과 같다.

package kr.smhrd.frontcontroller;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import kr.smhrd.controller.Controller;
import kr.smhrd.controller.MemberContentController;
import kr.smhrd.controller.MemberDeleteController;
import kr.smhrd.controller.MemberInsertController;
import kr.smhrd.controller.MemberListController;
import kr.smhrd.controller.MemberRegisterController;
import kr.smhrd.controller.MemberUpdateController;

@WebServlet("*.do")
//			DispatcherServlet(FrontController)
public class MemberFrontController extends HttpServlet {
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		// POST방식으로 넘어오는 경우에는 한글값을 인코딩해줄 필요가 있다.
		request.setCharacterEncoding("euc-kr");
		// GET방식은 한글로 넘어오는 경우가 거의 없으므로 인코딩 필요가 X.
		
		// 1. 클라이언트의 요청정보를 확인하기
		String reqUrl = request.getRequestURI(); // 클라이언트가 요청한 url정보를 얻어와서 reqUrl변수에 담아준다. 
//		System.out.println(reqUrl);
		
		// Context Path = ?
		String ctx = request.getContextPath();
//		System.out.println(ctx); // Context Path인 /mvc만 잘라내기
		
		// /memberList.do만 잘라오려면 어떻게 해야할까?
		String command = reqUrl.substring(ctx.length());	// RequestURI에서 ContextPath를 제외하면 ok!
		System.out.println(command);
		
		// 2. 해당 요청에 따른 분기 작업(HandlerMapping) : if ~ else ~
		Controller controller;
		String nextView = null;
		
		HandlerMapping mapping = new HandlerMapping();	// HandlerMapping 호출
		controller = mapping.getController(command);	// mapping에 command(ex:/memberList.do)를 넘긴다.
		nextView = controller.requestHandler(request, response);
		
		// ---------------------------------------------------
		// nextPage = "redirect:/mcv/memberList.do"
		// nextPage = "/WEB-INF/view/memberList.jsp"
		if (nextView != null) {
			if (nextView.indexOf("redirect:")!=-1) { // -1이 아니면 값이 있다는 뜻
				// redirect
				response.sendRedirect(nextView.split(":")[1]); // split해서 :기준으로 앞이 0, 뒤가 1. /mvc/memberList.do
			} else {
				// forward										// viewResolver : "/WEB-INF/view/"+nextView+".jsp"
				RequestDispatcher rd = request.getRequestDispatcher(ViewResolver.makeURL(nextView));
				rd.forward(request, response);
			}
		}
	}

}

www.egovframe.go.kr/home/ntt/nttRead.do?pagerOffset=0&searchKey=&searchValue=&menuNo=65&bbsId=4&nttId=1739

 

교육자료 | 표준프레임워크 포털 eGovFrame

처리중입니다. 잠시만 기다려주십시오.

www.egovframe.go.kr

여기에서 exe를 받아준다.

설치는 C:\에 진행한다.

 

이제부턴 완벽히 SPRING으로 바꾸는 작업을 진행할 것이다.

SPRING도 맨 처음 버전이 있고 최신 버전이 있다. 기본 틀은 변함이 없지만 틀 안에서 부수적인 부분이 변화가 있다. 

 

이제부터 전자정부 프레임워크를 사용할 것이므로 오라클 SQL이 아닌 MY SQL을 사용한다. 그리고 maven이라는 툴을 사용하게 될 것인데 이곳에 api가 모여있다.

 

여기에서 이클립스를 실행하면 이 화면이 뜬다.

블럭으로 잡은 부분을 지워준다. 절.대. 이클립스에서 지워줘야 한다. 다른 곳에서는 지우지 말자.

삭제 ok~

tomcat 서버에 프로젝트가 남아있다면 그것도 지워준다.

그리고 서버를 더블클릭하여 포트 번호를 바꾼다.

 

새로운 프로젝트를 생성하는데 우리에게 필요한게 바로 뜨진 않는다. other를 눌러서 spring 검색.

그림 순서대로 진행하고 next를 누르면 너가 요청한게 이거다. 진행할래? 물어본다. yes.

finish를 누르면 설치가 되고 열린다.

위 그림에서 보이는 m은 maven, s는 spring을 뜻한다고 한다.

사용환경을 java ee로 변경해준다. 처음 설정은 gGovFrame으로 되어있을 것이다.

난... 왜 오류가 나는가.... ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ

728x90
반응형
Comments