반응형

# 웹 애플리케이션 : 디렉토리 구조 생성

  • Java Project를 웹 애플리케이션 디렉토리 구조 형태로 변경하여 일련의 작업 진행. 
  • 학습을 위해 수동으로 디렉토리 구조 등 생성 진행.

1. 프로젝트 생성

  • Java Project 생성
  • 아래와 같이 webapp (홈디렉토리) 폴더 / WEB-INF 폴더 / classes 폴더 / lib 폴더 등 생성
  • WEB-INF에 web.xml 생성(XML File 로 생성)

2. web.xml 기본틀 생성

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee                       http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
    
    
    
</web-app>

 

# 웹 애플리케이션 : 웰컴 페이지 생성

1. index.html 생성 (HTML = 정적 페이지)

HTML File로 생성

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>웰컴 페이지</title>
</head>
<body>
웰컴 페이지 입니다.
</body>
</html>

2. Context 등록

  • 톰캣 서버가 인식할 수 있도록 등록해주는 것.
  • 방법1) Servers > server.xml 파일 열고 하단에 아래코드 추가
<Context path="/web" docBase="C:\eGovFrame-3.9.0\workspace.edu\WEB\webapp" />

3. 확인

  • http://localhost:8081/web 접속하여 확인.

 

# 웹 애플리케이션 : 동적 페이지 (JSP) 생성

1. servlet-api.jar 연결 (웹 애플리케이션 디렉토리를 수동으로 생성하여 jar파일 별도로 추가해줘야 함)

  • WEB용 API (servlet-api) 연결을 위해 아래파일 다운로드.

servlet-api.jar
0.23MB

  • 기존에 생성한 lib 폴더에 해당 jar 파일 추가.
  • 그리고 프로젝트 우 클릭하여 Properties 진입 후 Java Build Path 검색, Libraries에 해당 jar파일 넣어주기. (보통 Add External JARs로 추가하여 연결)

2. time.jsp 생성 (JSP = 동적 페이지)

  • JSP File로 생성
  • JSP는 HTML과 달리 프로그래밍이 가능. (Java + HTML)

3. 확인

  • http://localhost:8081/web/time.jsp 접속하여 확인

 

# 웹 애플리케이션 : 비즈니스 로직 분리 (Model 1 방식)

  • 우선 1~10 까지의 합을 구하는 클래스 생성

1. classes폴더 경로 설정

  • Java Project로 생성한 프로젝트는 src에 생성된 java 파일의 경우 소스 파일이 컴파일되면 bin폴더에 class 파일이 생성되도록 되어있다.
  • 지금 하는 프로젝트의 경우 소스 파일이 컴파일되면 classes 폴더에 class 파일이 들어가지도록 설계하여 아래와 같이 경로변경
  • 프로젝트 우클릭 > Properties > Java Build Path  > Source탭에서 경로 변경

2. package 생성

  • kr.web.util 패키지 생성

3. class 생성

  • MyUtil 클래스 생성
package kr.web.util;

public class MyUtil {
	public int hap() {
		int sum = 0;
		for ( int i = 1; i <= 10; i++ ) {
			sum += i;
		}
		
		return sum;
	}
}

4. sum.jsp에 MyUtil 클래스 연결

  • JSP File로 sum.jsp 생성
  • MyUtil 객체 생성하여 출력.
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@page import="kr.web.util.*" %>
<%
	MyUtil my = new MyUtil();
	
	int sum = my.hap();
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SUM 페이지</title>
</head>
<body>
	<table border="1">
		<tr>
			<td>1 ~ 10 까지의 총합</td>
			<td><%=sum %></td>
		</tr>
	</table>
</body>
</html>

5. 확인

  • http://localhost:8081/web/sum.jsp 접속하여 확인.

6. 디렉토리 구조

 

# 웹 애플리케이션 : 서블릿 (Servlet : Server + Let) , Servlet Mapping (web.xml 이용)

  • 서블릿은 특정 프로그램이 아님. 자바로 이루어져있는데 형태가 웹에서 동작할수 있는 형태이고, 톰캣 서버(WAS)에 의해 실행되는 클래스를 의미한다.
  • 서블릿의 골격 1. extends HttpServlet
  • 서블릿의 골격 2. HttpServlet의 Service(HttpServletRequest, HttpServletResponse) Override

1. package 생성

  • kr.web.controller 생성

2. class 생성

  • HelloServlet 생성
  • 아래가 Servlet의 기본 골격.
package kr.web.controller;

import java.io.IOException;

import javax.servlet.*;
import javax.servlet.http.*;

public class HelloServlet extends HttpServlet {
	public void service(HttpServletRequest request, HttpServletResponse response)
													throws ServletException, IOException {
		
	}
}
  • 아래는 1 ~ 10 까지의 총합을 구하는 로직.
package kr.web.controller;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.*;
import javax.servlet.http.*;

import kr.web.util.MyUtil;

public class HelloServlet extends HttpServlet {
	public void service(HttpServletRequest request, HttpServletResponse response)
													throws ServletException, IOException {
		// 1 ~ 10 총합
		MyUtil my = new MyUtil();
		int sum = my.hap();
		
		
		// 요청한 클라이언트에 응답하기.
		PrintWriter out = response.getWriter();
		out.println("<html>");
		out.println("<body>");
		out.println(sum);
		out.println("</body>");
		out.println("</html>");		
	}
}

3. Servlet Mapping

web.xml에 아래와 같이 입력하여 Mapping 진행

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee                       http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
    
    <servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>kr.web.controller.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/hs.do</url-pattern>
    </servlet-mapping>
    
</web-app>

  • 일반적으로 Servlet-name은 클래스 이름을 적어준다.

4. 확인

  • http://localhost:8081/web/hs.do 접속하여 확인

 

# 웹 애플리케이션 : Servlet Mapping (@WebServlet 이용)

1. 기존 class 변경

  • HelloServlet 에 @WebServlet("") 추가
package kr.web.controller;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;

import kr.web.util.MyUtil;

@WebServlet("/hs.do")
public class HelloServlet extends HttpServlet {
	public void service(HttpServletRequest request, HttpServletResponse response)
													throws ServletException, IOException {
		// 1 ~ 100 총합
		MyUtil my = new MyUtil();
		int sum = my.hap();
		
		
		// 요청한 클라이언트에 응답하기.
		PrintWriter out = response.getWriter();
		out.println("<html>");
		out.println("<body>");
		out.println(sum);
		out.println("</body>");
		out.println("</html>");		
	}
}

2. 기존 web.xml 변경

  • @WebServlet 사용에 따른 기존 입력내역 제거.
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee                       http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
    
</web-app>

3. 확인

  • http://localhost:8081/web/hs.do 접속하여 확인

 

# 웹 애플리케이션 : MySQL 데이터베이스 연결, MySQL table 생성

1 MySQL 서버 구동

  • C:\eGovFrame-3.9.0\bin\mysql-5.6.21 에서 startup.bat 실행하여 MySQL 서버 구동

2. MySQL Root 계정 암호 설정, 데이터베이스 생성

  • C:\eGovFrame-3.9.0\bin\mysql-5.6.21\bin 경로에서 cmd 오픈
  • root 계정 로그인을 위해 아래와 같이 입력
mysql -u root -p 입력 후 enter
비밀번호 입력하라는 경우 enter 진행 (기본적으로 초기에는 암호 X)
  • 데이터베이스 확인 방법은 아래와 같이 입력하여 확인
show databases;
  • root 계정 암호 설정은 아래와 같이 진행하여 암호 설정
use mysql;

update mysql.user set password=password('admin') where user='root' and host='localhost';
  • 변경사항 적용을 위해 아래와 같이 입력
flush privileges;
  • quit 로 나온 후 다시 root 계정으로 로그인, 신규 데이터베이스 생성
mysql -u root -p 입력하여 로그인

show databases; 입력하여 설치된 데이터베이스 확인

create database test; test라는 이름의 데이터베이스 생성

3. 이클립스-MySQL 연결

  • 자바에서 특정 데이터베이스 연결위해 드라이버 준비. (MySQL의 경우 mysql-connector-java.jar)

mysql-connector-java-5.1.31.jar
0.92MB

  • Data Source Explorer 탭 진입.
  • Database Connections 우 클릭 후 New 클릭, 연결하고자 하는 데이터베이스 선택
  • 우클 삼각형 (Edit Driver Definition) 클릭
  • JAR List에서 Add JAR/Zip 눌러서 데이터베이스 드라이버 (mysql-connector-java.jar) 연결
  • Properties에 아래와 같이 입력 (위에서 생성한 test 데이터베이스로 설정 그리고 Connection URL에 아래 추가)
jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8&serverTimezone=UTC

4. package 생성

  • kr.web.db

5. member.sql 생성

  • File로 member.sql 생성 아래 코드로 member table 생성
-- member table
create table member (
	num int primary key auto_increment,
	id varchar(20) not null,
	pass varchar(20) not null,
	name varchar(30) not null,
	age int not null,
	email varchar(30) not null,
	phone varchar(30) not null
)

select * from member;

## 완성한 web 프로젝트

MVC01.war
0.00MB

 

# 일반적인 Servlet 프로젝트 생성 (Dynamic Web Project)

위에서 수동으로 생성한 작업을 Dynamic Web Project 생성하여 자동으로 생성.

1. Dynamic Web Project 생성

  • project name : MVC01

2. Context 등록

  • Servers > 톰캣서버 우 클릭 > Add and Remove 진입
  • Available의 MVC01 프로젝트 클릭 후 Add 하여 Configured로 이동 후 Finish.
  • 이렇게 해주면 Servers의 Server.xml 하단에 Context 태그로 등록이 된다.

3. HTML 웰컴 페이지 생성

  • index.html 생성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>HTML 웰컴 페이지</title>
</head>
<body>

</body>
</html>

4. JSP 생성

test.jsp 생성 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	int sum = 0;
	for ( int i = 0; i <= 10; i++ ) {
		sum += i;
	}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JSP 웰컴 페이지</title>
</head>
<body>
<%=sum %>
</body>
</html>

5. 확인

  • http://localhost:8081/MVC01/index.html 접속하여 확인
  • http://localhost:8081/MVC01/test.jsp 접속하여 확인

6. package 생성

  • kr.bit.controller 패키지 생성

7. 서블릿 생성

  • New > Servlet 클릭
  • Class name : HelloStart  입력 후 Next

  • 하단 URL mapping을 /h.do로 변경 후 Next

  • 기본 메서드 service로 선택 후 Finish.

  • 이렇게 하면 기본적인 Servlet 골격이 자동으로 생성된다.
package kr.bit.controller;

import java.io.IOException;
import java.io.PrintWriter;

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

@WebServlet("/h.do")
public class HelloStart extends HttpServlet {
	protected void service(HttpServletRequest request, HttpServletResponse response) 
												throws ServletException, IOException {
		int sum = 0;
		
		for ( int i = 0; i <= 10; i++ ) {
			sum += i;
		}
		
		PrintWriter out = response.getWriter();
		out.println("<html>");
		out.println("<body>");
		out.println(sum);
		out.println("</body>");
		out.println("</html>");
	}

}

8. 확인

  • http://localhost:8081/MVC01/h.do 입력하여 확인

반응형
반응형

# MVC01~MVC04까지 완성된 소스파일 실행하는 방법 

MVC01.war
0.90MB
MVC02.war
0.89MB
MVC03.war
1.26MB
MVC04.war
1.25MB

1. 이클립스 실행

2. MySQL 서버 구동

  • C:\eGovFrame-3.9.0\bin\mysql-5.6.21 해당 경로에 가서 mysql bat 파일 (startup.bat) 실행하여 mysql 구동 (Ctrl + C 2번 누르면 종료)

3. 다운받은 WAR file Import

  • Project Explorer 빈 공간 우 클릭 > Import > WAR file 클릭 후 다운로드 받은 WAR file 클릭 후 Finish

4. 톰캣 서버 등록

  • Servers > 톰캣 서버 우 클릭 > Add and Remove
  • Available에서 Import 한 WAR file 클릭 후 Add 해서 Configured로 이동 후 Finish

## MVC01 sql 오류 해결방법

  • member.sql 에서 Select 문 등 실행 시
  • Plug-in org.eclipse.datatools.sqltools.result.ui was unable to load class org.eclipse.datatools.sqltools.result.internal.ui.view.ResultView.
  • 위와 같은 오류 발생 시 C:\eGovFrame-3.9.0\workspace.edu\.metadata\.plugins\org.eclipse.datatools.sqltools.result 경로에 가서 results 파일을 삭제 한 후 이클립스 재 실행하면 에러가 해결된다. (지울 땐 이클립스 삭제 후 지우기)
반응형
반응형

# MVC04_09 View의 경로를 만들어주는 ViewResolver

  • 기존에 POJO에서 경로를 리턴해 줄때 아래와 같이 리턴 해줬었는데, 경로를 모두 리턴할 경우 추후 폴더가 변경되는 등의 상황 발생 시 경로를 수정해줘야 하는 번거로움이 발생.
return "/WEB-INF/member/memberContent.jsp";
  • 그래서 View의 논리적인 이름만 리턴 될 수 있도록 변경 예정.
return "memberContent";

## ViewResolver

  • prefix와 subfix를 붙여서 하나의 논리적인 경로를 만들어내는 역할을 하는 클래스.

### prefix 와 subfix

  • 아래 경로 에서 논리 경로를 기준으로 앞부분을 prfix, 뒷 부분을 subfix 라고 한다.
return "/WEB-INF/member/memberContent.jsp";

여기서 논리적인 경로 memberContent을 기준으로.

앞 부분을 prefix

뒷 부분을 subfix 

라고 한다.

### ViewResolver 작업 진행_1 : 임시로 FrontController 에서 prefix, subfix 추가하여 논리경로 생성

  • 기존 memberRegister.html 을 jsp로 변경
  • MemberContentController 리턴 값 변경 -> 기존 전체 경로에서 return "memberContent"; 로 변경
  • MemberListController 리턴 값 변경 -> 기존 전체 경로에서 return "memberList"; 로 변경
  • MemberRegisterController 리턴 값 변경 -> 기존 전체 경로에서 return "memberRegister"; 로 변경
  • FrontController 에서 prefix, subfix 추가
package kr.bit.frontController;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

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.bit.controller.Controller;
import kr.bit.controller.MemberContentController;
import kr.bit.controller.MemberDeleteController;
import kr.bit.controller.MemberInsertController;
import kr.bit.controller.MemberListController;
import kr.bit.controller.MemberRegisterController;
import kr.bit.controller.MemberUpdateController;
import kr.bit.model.MemberDAO;
import kr.bit.model.MemberVO;

@WebServlet("*.do")
public class MemberFrontController extends HttpServlet {
	protected void service(HttpServletRequest request, HttpServletResponse response) 
							throws ServletException, IOException {
		
		// 한글 깨짐 방지
		request.setCharacterEncoding("utf-8");
		// 1. 클라이언트가 어떤 요청을 했는지 파악하기. 
		// (request를 이용하면 클라이언트가 어떤 요청을 했는지 파악 가능)
		String url = request.getRequestURI();
		// System.out.println("url : " + url); 				url 확인
		// /MVC04/memberList.do 이런식으로 출력되는 것 확인 가능.
		
		// 컨택스트 가져오기	
		String ctx = request.getContextPath();
		// System.out.println("ctx : " + ctx);				contextPath 확인
		// /MVC04 이런식으로 출력되는 것 확인 가능.
		
		// 2. 실제로 요청한 명령이 무엇인지 파악(contextPath 제외한 url)
		String command = url.substring(ctx.length());	
		// System.out.println("command : " + command);		클라이언트가 서버에 요청한 실제 command
		// memberList.do 등이 출력된다.
		
		// Controller _ POJO 연결 위함
		Controller controller = null;
		String nextPage = null;
		
		// 3. 요청에 따른 분기 작업. -> HandlerMapping에서 진행
		HandlerMapping mapping = new HandlerMapping();
		controller = mapping.getController(command);
		nextPage = controller.requestHandler(request, response);
		
		// forward, redirect
		if(nextPage != null ) {
			if(nextPage.indexOf("redirect:") != -1) {	// redirect: 라는 글자 존재 시 redirect
				response.sendRedirect(nextPage.split(":")[1]);
			} else {
				// ViewResolver 작업 -> prefix랑 subfix 앞뒤에 붙여 논리적인 경로 완성
				RequestDispatcher rd = request.getRequestDispatcher("/WEB-INF/member/" + nextPage + ".jsp");
				rd.forward(request, response);
			}
		}
	}
}

### ViewResolver 작업 진행_2 : ViewResolver 클래스 생성해서 논리경로 생성

  • 프로젝트 > src > kr.bit.frontcontroller > class > ViewResolver 이름의 클래스 생성
  • 아래와 같이 작업 해주면 이후에 경로가 수정되는 상황 발생 시 해당 클래스에서 경로 수정해주면 된다.
package kr.bit.frontController;

public class ViewResolver {
	public static String makeView(String nextPage) {
		return "/WEB-INF/member/" + nextPage + ".jsp";
	}
}
  • FrontController  수정 (ViewResolver 로 작업 될 수 있도록 변경)
package kr.bit.frontController;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

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.bit.controller.Controller;
import kr.bit.controller.MemberContentController;
import kr.bit.controller.MemberDeleteController;
import kr.bit.controller.MemberInsertController;
import kr.bit.controller.MemberListController;
import kr.bit.controller.MemberRegisterController;
import kr.bit.controller.MemberUpdateController;
import kr.bit.model.MemberDAO;
import kr.bit.model.MemberVO;

@WebServlet("*.do")
public class MemberFrontController extends HttpServlet {
	protected void service(HttpServletRequest request, HttpServletResponse response) 
							throws ServletException, IOException {
		
		// 한글 깨짐 방지
		request.setCharacterEncoding("utf-8");
		// 1. 클라이언트가 어떤 요청을 했는지 파악하기. 
		// (request를 이용하면 클라이언트가 어떤 요청을 했는지 파악 가능)
		String url = request.getRequestURI();
		// System.out.println("url : " + url); 				url 확인
		// /MVC04/memberList.do 이런식으로 출력되는 것 확인 가능.
		
		// 컨택스트 가져오기	
		String ctx = request.getContextPath();
		// System.out.println("ctx : " + ctx);				contextPath 확인
		// /MVC04 이런식으로 출력되는 것 확인 가능.
		
		// 2. 실제로 요청한 명령이 무엇인지 파악(contextPath 제외한 url)
		String command = url.substring(ctx.length());	
		// System.out.println("command : " + command);		클라이언트가 서버에 요청한 실제 command
		// memberList.do 등이 출력된다.
		
		// Controller _ POJO 연결 위함
		Controller controller = null;
		String nextPage = null;
		
		// 3. 요청에 따른 분기 작업. -> HandlerMapping에서 진행
		HandlerMapping mapping = new HandlerMapping();
		controller = mapping.getController(command);
		nextPage = controller.requestHandler(request, response);
		
		// forward, redirect
		if(nextPage != null ) {
			if(nextPage.indexOf("redirect:") != -1) {	// redirect: 라는 글자 존재 시 redirect
				response.sendRedirect(nextPage.split(":")[1]);
			} else {
				// ViewResolver 작업
				// ViewResolver 클래스에서 경로 가져올수 있도록 변경
				RequestDispatcher rd = request.getRequestDispatcher(ViewResolver.makeView(nextPage));
				rd.forward(request, response);
			}
		}
	}
}

 

# MVC04_10 Context Path가 변경되어도 동일한 경로 유지하기

  • Servers > server.xml
  • 만약 기존 MVC04 가 MVC로 바뀌게 되면 memberContent.jsp 등에 /MVC04/memberUpdate.do 로 되어있는 부분을 일일이 확인해서 수정해 줘야 한다. (수정은 어렵지 않지만 번거로움)
server.xml 에서..

<Context docBase="MVC04" path="/MVC04" reloadable="true" source="org.eclipse.jst.jee.server:MVC04"/></Host>

여기서 path 가 Context Path.
  • 현재 프로젝트의 Context Path를 자동으로 가져와서 Context Path 자리에 출력해주면 될 것.

## Context Path 가져오기

  • 아래 코드 이용해서 Context Path 가져오기
String ctx = request.getContextPath();

## Context Path 가져오는 활용한 변경 작업

  • 우선 Controller 변경 작업 진행

1. MemberDeleteController

package kr.bit.controller;

import java.io.IOException;

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

import kr.bit.model.MemberDAO;

public class MemberDeleteController implements Controller {

	@Override
	public String requestHandler(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		// Context Path 가져오기
		String ctx = request.getContextPath();	// MVC04가 옴
		
		int num = Integer.parseInt(request.getParameter("num"));
		
		MemberDAO dao = new MemberDAO();
		
		int cnt = dao.memberDelete(num);
		
		String nextPage = null;
		
		if (cnt > 0) {
			nextPage = "redirect:" + ctx + "/memberList.do";	// Context Path 추가
		} else {
			throw new ServletException("not delete");
		}
		
		return nextPage;
	}

}

2. MemberInsertController

package kr.bit.controller;

import java.io.IOException;
import java.io.PrintWriter;

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

import kr.bit.model.MemberDAO;
import kr.bit.model.MemberVO;

public class MemberInsertController implements Controller {

	@Override
	public String requestHandler(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		// Context Path 가져오기
		String ctx = request.getContextPath();	// MVC04가 옴
				
		// 1. 파라미터 수집(VO)
		String id = request.getParameter("id");
		String pass = request.getParameter("pass");
		String name = request.getParameter("name");
		int age = Integer.parseInt(request.getParameter("age"));
		String email = request.getParameter("email");
		String phone = request.getParameter("phone");
		
		// 파라미터 수집(VO)
		// MemberVO vo = new MemberVO(id, pass, name, age, email, phone);
		MemberVO vo = new MemberVO();		
		vo.setId(id);
		vo.setPass(pass);
		vo.setName(name);
		vo.setAge(age);
		vo.setEmail(email);
		vo.setPhone(phone);
		
		//System.out.println("vo : " + vo);	// vo.toString() 이 생략되어있는 것.
		// Model과 연동하는 부분
		MemberDAO dao = new MemberDAO();
		int cnt = dao.memberInsert(vo);
		
		// PrintWriter out = response.getWriter();
		String nextPage = null;
		// 가입 성공
		if ( cnt > 0 ) {
			//out.println("insert success");	
			// 다시 회원 리스트 보기로 가야함.
			// response.sendRedirect("/MVC04/memberList.do");
			nextPage = "redirect:" + ctx + "/memberList.do";	// Context Path 추가
		// 가입 실패 -> 예외 객체를 만들어서 WAS에게 던지자.
		} else {
			throw new ServletException("not insert");	
		}
		return nextPage;
	}

}

3. MemberUpdateController

package kr.bit.controller;

import java.io.IOException;

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

import kr.bit.model.MemberDAO;
import kr.bit.model.MemberVO;

public class MemberUpdateController implements Controller {

	@Override
	public String requestHandler(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		// Context Path 가져오기
		String ctx = request.getContextPath();	// MVC04가 옴
				
		request.setCharacterEncoding("utf-8");
		// 1. 파라미터 수집(VO)
		int num = Integer.parseInt(request.getParameter("num"));
		int age = Integer.parseInt(request.getParameter("age"));
		String email = request.getParameter("email");
		String phone = request.getParameter("phone");
	
		MemberVO vo = new MemberVO();
		vo.setNum(num);
		vo.setAge(age);
		vo.setEmail(email);
		vo.setPhone(phone);
	
		MemberDAO dao = new MemberDAO();
		
		int cnt = dao.memberUpdate(vo);
		
		String nextPage = null;
		
		if (cnt > 0) {
			nextPage = "redirect:" + ctx + "/memberList.do";	// Context Path 추가
		} else {
			throw new ServletException("not update");
		}
		
		return nextPage;
	}

}
  • jsp 변경작업 진행
  • jsp에서는 아래와 같이 Context Path 가져오기
<!-- Context Path 가져오기 -->
<c:set var="ctx" value="${pageContext.request.contextPath}"/>

<!-- 가져온 Context Path 사용 -->
${ctx}

1. memberContent.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="kr.bit.model.*" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
	// JSTL 사용 전
	// MemberVO vo = (MemberVO)request.getAttribute("vo");
%>    
<!-- Context Path 가져오기 -->
<c:set var="ctx" value="${pageContext.request.contextPath}"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<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>
</head>
<body>
<form action="${ctx}/memberUpdate.do" method="post">
<input type="hidden" name="num" value="${vo.getNum()}"/>
	<table border="1" class="table table-bordered">
	<c:if test="${vo != null}">
		<tr>
			<td colspan="2">${vo.getName()} 회원의 상세보기</td>
		</tr>
		<tr>
			<td>번호</td>
			<td>${vo.getNum()}</td>
		</tr>
		<tr>
			<td>아이디</td>
			<td>${vo.getId()}</td>
		</tr>
		<tr>
			<td>비밀번호</td>
			<td>${vo.getPass()}</td>
		</tr>
		<tr>
			<td>이름</td>
			<td>${vo.getName()}</td>
		</tr>
		<tr>
			<td>나이</td>
			<td><input type="text" name="age" value="${vo.getAge()}" /></td>
		</tr>
		<tr>
			<td>이메일</td>
			<td><input type="text" name="email" value="${vo.getEmail()}" /></td>
		</tr>
		<tr>
			<td>전화번호</td>
			<td><input type="text" name="phone" value="${vo.getPhone()}" /></td>
		</tr>
	</c:if>
		<tr>
			<td colspan="2" align="center">
				<input type="submit" value="수정하기" class="btn btn-primary" />
				<input type="reset" value="취소" class="btn btn-warning" />
				<input type="button" value="리스트" onclick="location.href='${ctx}/memberList.do'" class="btn" />
			</td>
		</tr>
	</table>
</form>
</body>
</html>

2. memberList.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="kr.bit.model.*" %>
<%@ page import="java.util.*" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
	// JSTL 사용 전.
	// ArrayList<MemberVO> list = (ArrayList<MemberVO>) request.getAttribute("list");
%>
<!-- Context Path 가져오기 -->
<c:set var="ctx" value="${pageContext.request.contextPath}"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<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>
	function deleteFn(num) {
		location.href="${ctx}/memberDelete.do?num=" + num;
	}
</script>
</head>
<body>
[MVC04 예제 - FrontController + POJO]
<table class="table table-bordered">
	<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.getNum()}</td>
			<td><a href="${ctx}/memberContent.do?num=${vo.getNum()}">${vo.getId()}</a></td>
			<td>${vo.getPass()}</td>
			<td>${vo.getName()}</td>
			<td>${vo.getAge()}</td>
			<td>${vo.getEmail()}</td>
			<td>${vo.getPhone()}</td>
			<td><input type="button" value="삭제" class="btn btn-warning" onclick="deleteFn(${vo.getNum()})" /></td>
		</tr>
	</c:forEach>
	<tr>
		<td colspan="8" align="right"><input type="button" value="회원가입" class="btn btn-primary" onclick="location.href='${ctx}/memberRegister.do'"/></td>
	</tr>
</table>
</body>
</html>

3. memberRegister.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!-- Context Path 가져오기 -->
<c:set var="ctx" value="${pageContext.request.contextPath}"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>신규 회원 가입</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>
</head>
<body>
<h1>회원가입화면</h1>
<form action="${ctx}/memberInsert.do" method="POST" >
	<table class="table table-bordered">
	  <tr>
	    <td>아이디</td>
	    <th><input type="text" name="id" /></th>
	  </tr>
	  <tr>
	    <td>패스워드</td>
	    <th><input type="password" name="pass" /></th>
	  </tr>
	  <tr>
	    <td>이름</td>
	    <th><input type="text" name="name" /></th>
	  </tr>
	  <tr>
	    <td>나이</td>
	    <th><input type="text" name="age" /></th>
	  </tr>
	  <tr>
	    <td>이메일</td>
	    <th><input type="text" name="email" /></th>
	  </tr>
	  <tr>
	    <td>전화번호</td>
	    <th><input type="text" name="phone" /></th>
	  </tr>
	  <tr>
	    <td colspan="2" align="center">
	    	<input type="submit" value="가입" class="btn btn-primary"/>
			<input type="reset" value="취소" class="btn btn-warning"/>
	    </td>
	  </tr>
	</table>
</form>
</body>
</html>
반응형
반응형

# MVC04_07 forward와 redirect 구분

## 핸들러 매핑 (HandlerMapping)

  • 여기서 핸들은 경로를 의미
  • 이후 핸들러 매핑을 FrontController에서 진행하는게 아닌 별도의 클래스에서 진행 하도록 변경 할 예정.
  • 아래 코드는 기존 핸들러 매핑 부분 여기서 중첩되는 부분을 따로 빼서 처리예정
// 핸들러 매핑 (여기서 핸들은 경로(/memberList.do 등)를 의미.
		if (command.equals("/memberList.do")) {				// 회원 리스트 화면
			controller = new MemberListController();
			nextPage = controller.requestHandler(request, response);
			RequestDispatcher rd = request.getRequestDispatcher(nextPage);
			rd.forward(request, response);
		} else if (command.equals("/memberInsert.do")) {	// 회원 가입
			controller = new MemberInsertController();
			nextPage = controller.requestHandler(request, response);
			response.sendRedirect(nextPage);
		} else if (command.equals("/memberRegister.do")) {	// 회원 가입 화면
			controller = new MemberRegisterController();
			nextPage = controller.requestHandler(request, response);
			RequestDispatcher rd = request.getRequestDispatcher(nextPage);
			rd.forward(request, response);
		} else if (command.equals("/memberContent.do")) {	// 회원 상세보기 화면
			controller = new MemberContentController();
			nextPage = controller.requestHandler(request, response);
			RequestDispatcher rd = request.getRequestDispatcher(nextPage);
			rd.forward(request, response);
		} else if (command.equals("/memberUpdate.do")) {	// 회원 정보 수정
			controller = new MemberUpdateController();
			nextPage = controller.requestHandler(request, response);
			response.sendRedirect(nextPage);
		} else if (command.equals("/memberDelete.do")) {	// 회원 정보 삭제
			controller = new MemberDeleteController();
			nextPage = controller.requestHandler(request, response);
			response.sendRedirect(nextPage);
		}
  • 아래 처럼 공통 부분을 별도로 빼서 작업 진행
// 핸들러 매핑 (여기서 핸들은 경로(/memberList.do 등)를 의미.
		if (command.equals("/memberList.do")) {				// 회원 리스트 화면
			controller = new MemberListController();
			nextPage = controller.requestHandler(request, response);
		} else if (command.equals("/memberInsert.do")) {	// 회원 가입
			controller = new MemberInsertController();
			nextPage = controller.requestHandler(request, response);
		} else if (command.equals("/memberRegister.do")) {	// 회원 가입 화면
			controller = new MemberRegisterController();
			nextPage = controller.requestHandler(request, response);
		} else if (command.equals("/memberContent.do")) {	// 회원 상세보기 화면
			controller = new MemberContentController();
			nextPage = controller.requestHandler(request, response);
		} else if (command.equals("/memberUpdate.do")) {	// 회원 정보 수정
			controller = new MemberUpdateController();
			nextPage = controller.requestHandler(request, response);
		} else if (command.equals("/memberDelete.do")) {	// 회원 정보 삭제
			controller = new MemberDeleteController();
			nextPage = controller.requestHandler(request, response);
		}
		
		// forward, redirect
		if(nextPage != null ) {
			if(nextPage.indexOf("redirect:") != -1) {	// redirect: 라는 글자 존재 시 redirect
				response.sendRedirect(nextPage.split(":")[1]);
			} else {
				RequestDispatcher rd = request.getRequestDispatcher(nextPage);
				rd.forward(request, response);
			}
		}

 

# MVC04_08 HandlerMapping HashMap 활용

  • FrontController에서 핸들러 매핑되는 부분(if ~ else if로 분기처리 하는 부분)을 별도의 클래스에서 작업할 수 있도록 변경 예정
  • HashMap을 이용하여 key, value 값으로 요청에 따른 분기처리 진행

  • HashMap에 입력 시 put 사용, 출력 시 get 사용

## HandlerMapping 생성

  • 프로젝트 > kr.bit.frontController > class > HandlerMapping 이름으로 생성
package kr.bit.frontController;

import java.util.HashMap;

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

public class HandlerMapping {
	private HashMap<String, Controller> mappings;
	
	public HandlerMapping() {
		mappings = new HashMap<String, Controller>();
		mappings.put("/memberList.do",		new MemberListController());
		mappings.put("/memberInsert.do",	new MemberInsertController());
		mappings.put("/memberRegister.do",	new MemberRegisterController());
		mappings.put("/memberContent.do",	new MemberContentController());
		mappings.put("/memberUpdate.do",	new MemberUpdateController());
		mappings.put("/memberDelete.do",	new MemberDeleteController());
	}
	
	public Controller getController(String key) {	// key = /memberList.do 등의 경로 들어옴
		return mappings.get(key);		
	}
}

## FrontController HandlerMapping 변경

  • 기존 FrontController에서 핸들러 매핑되는 부분을 별도로 생성한 HandlerMapping에서 처리하도록 변경
package kr.bit.frontController;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

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.bit.controller.Controller;
import kr.bit.controller.MemberContentController;
import kr.bit.controller.MemberDeleteController;
import kr.bit.controller.MemberInsertController;
import kr.bit.controller.MemberListController;
import kr.bit.controller.MemberRegisterController;
import kr.bit.controller.MemberUpdateController;
import kr.bit.model.MemberDAO;
import kr.bit.model.MemberVO;

@WebServlet("*.do")
public class MemberFrontController extends HttpServlet {
	protected void service(HttpServletRequest request, HttpServletResponse response) 
							throws ServletException, IOException {
		
		// 한글 깨짐 방지
		request.setCharacterEncoding("utf-8");
		// 1. 클라이언트가 어떤 요청을 했는지 파악하기. 
		// (request를 이용하면 클라이언트가 어떤 요청을 했는지 파악 가능)
		String url = request.getRequestURI();
		// System.out.println("url : " + url); 				url 확인
		// /MVC04/memberList.do 이런식으로 출력되는 것 확인 가능.
		
		// 컨택스트 가져오기	
		String ctx = request.getContextPath();
		// System.out.println("ctx : " + ctx);				contextPath 확인
		// /MVC04 이런식으로 출력되는 것 확인 가능.
		
		// 2. 실제로 요청한 명령이 무엇인지 파악(contextPath 제외한 url)
		String command = url.substring(ctx.length());	
		// System.out.println("command : " + command);		클라이언트가 서버에 요청한 실제 command
		// memberList.do 등이 출력된다.
		
		// Controller _ POJO 연결 위함
		Controller controller = null;
		String nextPage = null;
		
		// 3. 요청에 따른 분기 작업. -> HandlerMapping에서 진행
		HandlerMapping mapping = new HandlerMapping();
		controller = mapping.getController(command);
		nextPage = controller.requestHandler(request, response);
		
		// forward, redirect
		if(nextPage != null ) {
			if(nextPage.indexOf("redirect:") != -1) {	// redirect: 라는 글자 존재 시 redirect
				response.sendRedirect(nextPage.split(":")[1]);
			} else {
				RequestDispatcher rd = request.getRequestDispatcher(nextPage);
				rd.forward(request, response);
			}
		}
	}
}
반응형

+ Recent posts