본문 바로가기

수업 정리

52일차 수업 정리(HttpServlet, Model2 MVC 구조의 프로젝트 생성)

**HttpServlet

    => URL을 이용해서 호출할 수 있는 Java EE의 클래스

    => Java SE 버전을 설치하고 이 클래스를 사용하려면 Spring같은 프레임워크 or WAS(Tomcat)를 사용해야 함

    => Servlet이나 jsp 파일 추가시 에러가 발생하는데

        - 에러를 제거하고자 하면 servlet-api.jar 파일을 프로젝트의 WebContent/WEB_INF/lib 디렉토리에 복사 해야 함

    => Servlet은 매핑이 되는 첫번째 요청시 인스턴스 생성, 요청을 처리한 후 WAS가 관리

        - 두번째 요청부터는 이전에 만든 인스턴스를 이용하여 요청 처리

    => 이 클래스 제작시 HttpServlet이라는 클래스를 상속받아서 생성

    => jsp는 HTML코드 안에 Java코드를 삽입하는 형태, Servlet은 Java코드 안에 HTML을 삽입할 수 있음

        - jsp 파일에는 EL과 JSTL을 이용하여 출력하는 코드만 작성

        - 처리 작업은 Servlet과 Java 클래스를 이용하는 형태로 코딩하는 것을 권장(Model2)

1. 작성 방법

    => HttpServlet 클래스로부터 상속받는 클래스를 생성

        - 생성시 매핑이 되는 URL설정 가능하고, 나중에 web.xml 파일에 매핑이 되는 URL설정 가능

    => 요청을 처리하는 메소드를 재정의

        - doGet, doPost메소드를 이용한 방식이 있고, service 메소드를 이용하는 방식도 있음

        - doGet은 get방식 요청시 호출, doPost는 post방식 요청시 호출되는 메소드

        - service는 요청방식에 상관없이 호출되는 메소드(잘 사용되지 않음)

    => 서블릿 생성시 doGet과 doPost가 이미 재정의 되어 있음

        - doPost메소드에는 doGet을 호출하는 문장이 있어 실제로는 doGet에만 코딩하면 됨

 

2. 서블릿에서의 내장 객체 사용

    => doGet 메소드와 doPost메소드의 매개변수로 request객체와 response 객체가 전달됨

    => session 객체는 request.getSession() 메소드를 호출하여 리턴된 객체를 사용

    => application 객체는 request.getServletContext() 메소드를 호출하여 리턴된 객체 사용

    => 출력을 할 때는 response.getWriter()를 호출하여 리턴된 객체를 사용

 

3. 서블릿과 URL매핑

  1) annotation을 이용한 방법

    => servlet 클래스 상단에 어노테이션을 추가

        - @WebServlet("URL")

  2) web.xml을 이용한 방법 - 권장하지 않음

<servlet>
	<servlet-name>서블릿 이름</servlet-name>
	<servlet-class>서블릿 클래스 경로</servlet-class>
</servlet>

<servlet-mapping>
	<servlet-name>서블릿 이름</servlet-name>
	<url-pattern>url 패턴</url-pattern>
</servlet-mapping>

 

4. 서블릿 생성 및 호출 실습

  1) FirstServlet.java 파일 제작


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

/**
 * Servlet implementation class FirstServlet
 */
//URL 매핑을 해주는 어노테이션
@WebServlet("/FirstServlet")
public class FirstServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
	//생성자
    public FirstServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
    //get방식의 요청이 온 경우 처리하는 메소드
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.getWriter().append("Served at: ").append(request.getContextPath());
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	//post방식의 요청이 온 경우 처리하는 메소드
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//post 방식의 요청을 doGet에서 처리할 수 있도록 doGet 메소드 호출
		doGet(request, response);
	}

}

  2) 서블릿 호출

    => 웹 애플리케이션 실행후 브라우저의 주소 표시줄에 @WebServlet("/FirstServlet")에 설정된 URL을 추가로 입력

 

5. URL Pattern

    => 서블릿은 생성하면 하나의 URL과 매핑

    => 여러개의 요청을 처리하는 경우 여러개의 서블릿이 필요

    => 여러개의 URL을 묶어서 하나의 서블릿으로 처리할 수 있음

        - 하나의 객체가 하나의 이벤트를 처리 할 수 있는데 이렇게 하면 여러개의 이벤트 처리를 위해 여러 객체가 필요

        - 여러개의 이벤트를 하나의 객체를 이용하여 처리하도록 하는 것을 이벤트 라우팅이라고 함

    => 모든 웹 프로그래밍에서는 전부 이런식으로 하나의 객체를 가지고 여러 URL을 처리

  1) 모든 요청을 처리

    - URL을 /*로 설정

  2) 확장자 패턴 - 우리나라에서 많이 사용

    - *.확장자 로 설정

    => 확장자로 끝나는 모든 요청을 처리

    => 우리나라 공공기관은 do 확장자를 많이 사용

        - 네이버는 nhn

  3) 디렉토리 패턴 - 최근에 권장

    - /디렉토리/*로 설정

    => 디렉토리가 포함된 모든 요청을 처리

    => 디렉토리에 작업의 의미를 부여해서 알아보기 쉽게 URL을 만드는 것을 권장

    => 최근은 파라미터가 1개인 경우 파라미터없이 디렉토리 패턴 마지막에 파라미터를 설정하는 방식이 많이 사용됨

  4) 확장자 패턴과 디렉토리 패턴은 같이 사용 불가

    => /디렉토리/*.확장자 형태는 안됨

 

6. Controller Pattern

    => 요청이 발생시 반드시 Controller를 거쳐서 나가도록 하는 패턴

    => 요청이 발생 할 때, 거치도록 하면 FrontController 패턴이라고 함

    => 실제 업무에서 요청 발생시 그에 따른 공통 관심사항이라고 부르는 Common Concern이 있는 경우가 많음

        - 이러한 작업은 한곳에서 수행할 수 있도록 만드는 것이 유지보수에 유리

    => 자바에서는 Controllerf\를 서블릿으로 생성

    => 다른 애플리케시여 개발시에도 시작하는 클래스를 찾아두는 것이 중요

 

7. Controller 패턴을 만들기 위해서 알아야 할 내용

    - request.getContextPath() : 루트 경로를 문자열로 리턴해주는 메소드,

    - requsetgetRequestURL() : 전체 요청 경로를 문자열로 리턴해주는 메소드

    - request.getMethod() : 요청 방식을 문자열로 리턴해주는 메소드(GEtT, POST)

 

  포워딩

    - requestDispatcher ?= request.getRequestDispatcher("포워딩 할 URL");

    - ?.forward(request객체, response객체);

    => URL을 변경하지 않고 이동

 

  리다이렉트

    - request객체.sendRedirect("리다이렉트 할 URL");

 

8. 디렉토리 패턴을 이용한 페이지 이동

    - jsp 파일은 ex 디렉토리에 생성

    - /authentication 디렉토리 패턴을 이용

  1) WebContent 디렉토리 내에 ex 디렉토리를 만들고 main.jsp 파일 생성 

<!-- main.jsp -->
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- JSTL의 core 기능을 사용할 수 있도록 태그 라이브러리 설정 -->
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>메인 화면</title>
</head>
<body>
	<!-- 로그인 여부는 대부분 session에 로그인을 했을 때 
	로그인과 관련된 어떤 값을 저장해두고 값의 저장 여부에 따라 판단 -->
	<c:if test="${id == null}">
		<a href="${pageContext.request.contextPath}/authentication/login">로그인</a><br/>
	</c:if>
	<c:if test="${id != null}">
		<a href="${pageContext.request.contextPath}/authentication/logout">로그아웃</a><br />
	</c:if>
		
	<a href="${pageContext.request.contextPath}/authentication/write">글쓰기</a><br />

</body>
</html>


 

  2) ex 디렉토리에 login.jsp 파일을 생성

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인</title>
</head>
<body>
	<form action="login" method="post">
		아이디<input type="text" name="id", id="id"/><br/>
		비밀번호<input type="password" name="pw", id="pw"/><br/>
		<input type="submit" value="로그인"/>
		<input type="button" value="메인으로"/>
	</form>
</body>
</html>

 

  3) ex 디렉토리에 write.jsp 파일을 생성

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>글쓰기</title>
</head>
<body>
	<p>글쓰기 페이지</p>
	<p>이 페이지는 로그인이 되어있는 경우에만 사용이 가능</p>
</body>
</html>

 

  4) /authentication 디렉토리가 포함된 요청을 처리할 수 있는 서블릿을 생성하고 doGet메소드를 수정

    => 폼 입력 화면으로 이동하는 것과 폼 요청을 처리하는 URL을 동일하게 하는 것을 권장

    => 전송방식을 이용하여 폼 입력화면 으로 갈 때는 GET 방식으로 포워딩

        - 폼 요청 처리하는 곳으로 갈때는 POST방식으로 리다이렉트 하는 것을 권장

//AuthenticationControllor.java

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;


@WebServlet("/authentication/*")
public class AuthenticationControllor extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public AuthenticationControllor() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//루트 경로 찾아오기
		String contextPath = request.getContextPath();
		//사용자의 요청 경로 찾기
		String requestURI = request.getRequestURI();
		//사용자의 요청 경로를 가지고 라우팅 가능
		//사용자의 요청 경로에는 루트 경로가 포함되어 있음
		//공통된 부분을 제외한 부분만 추출
		//여기까지 작업은 프레임워크가 해줌
		
		String routePath = requestURI.substring(contextPath.length() + 16);
		System.out.println(routePath);
		
		//전송방식을 찾아옴 - GET, POST
		String method = request.getMethod(); 
		
		//포워딩에 사용할 변수
		RequestDispatcher dispatcher = null;
		
		//라우팅
		switch (routePath) {
		//폼 요청과 
		case "login":	
			if(method.equals("GET")) {
				dispatcher = request.getRequestDispatcher("../ex/login.jsp");
				dispatcher.forward(request, response);
			}else {
				//로그인 처리 - main.jsp로 이동하도록 작성
				//리다이렉트할 때 파일로 직접 리다이렉트 하지 말고, 요청으로 리다이렉트 한 후
				//그 요청을 처리하는 곳에서 포워딩하는 것을 권장
				response.sendRedirect("main");
			}
			break;
		case "main":
			dispatcher = request.getRequestDispatcher("../ex/main.jsp");
			dispatcher.forward(request, response);
			break;
		case "write":
			dispatcher = request.getRequestDispatcher("../ex/write.jsp");
			dispatcher.forward(request, response);
			break;

		default:
			break;
		}
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

  5) WebContext 디렉토리에 시작페이지로 사용할 index.jsp파일을 만들고 링크를 추가

 

9. 서블릿과 jsp의 수명주기

    => 서블릿은 매핑되는 첫번째 URL요청이 올때, 인스턴스를 만들고 요청 처리후, 다음요청들을 만든 인스턴스로 처리

    => jsp는 매핑되는 요청이 올 때마다 서블릿 클래스로 변환하고 인스턴스를 만든후 요청을 처리하고 삭제

  1) 서블릿 인스턴스를 요청이 오기 전에 서버가 구동되면 바로 만들수 있음

    - 이경우는 web.xml 파일에 등록을 하면 됨

<servlet>
	<servlet-name>이름</servlet-name>
    <servlet-class>클래스 경로</servlet-class>
    <load-on-startup>정수</load-on-startup>
</servlet>

    => 실제 서블릿은 전부 위처럼 옵션을 설정

    => 정수는 생성되는 순서로 작은 숫자로 설정한 것이 먼저 생성됨

  2) 서블릿 초기화와 소멸에 관련된 메소드

    => init을 재정의하여 초기화

    => destroy를 재정의하여 소멸될 때 수행할 작업을 작성

    => jsp는 jspInit와 jspDestroy를 이용

 

10. Model2 MVC Pattern

    => Command Pattern : 하나의 명령은 하나의 객체가 처리

        - 하나의 요청은 하나의 메소드와 매핑되어야 함

    => Model2 : 출력은 jsp에서 처리는 servlet이나 java class가 수행

    => MVC : 처리와 출력을 분할하고 이 둘을 연결시켜주는 Controller를 생성하는 패턴

        - Model이 모든 요청을 처리하고, View가 출력, Controller는 연결만 담당하도록 작성

        - Model은 다시 2개 부분으로 나뉨(service : 알고리즘을 처리, Repository : 데이터 관련 작업 처리)

    => 웹 프로젝트의 기본 구조

        - View(jsp나 html) <-> Controller(HttpServlet) <-> Service(Java Class) <-> Repository(Java) <-> 데이터 저장소

        - 여러 유저가 접속해서 사용하는 시스템(금융)에서는 데이터저장소와 Repository사이 Middle Ware를 두기도 함

        - 사용자의 요청 1개는 Service에서는 1개의 메소드만 호출 해야 함(이후 메소드 여러개 호출하는 것은 상관없음)

        - Service 부분은 템플릿 메소드 패턴(인터페이스 -> 클래스)을 사용하는 것을 권장

        - 서버에서 구동되는 클래스들은 싱글톤패턴(인스턴스를 1개만 생성가능한 클래스)으로 디자인하는 것을 권장

          (동일한 여러개의 요청이 온 경우 하나의 인스턴스가 스레드를 이용하여 처리(여러개의 인스턴스X)

        - Controller 제작시 대부분의 경우 URL 패턴을 /* 또는 jsp를 제외한 모든 요청을 처리(학습시를 제외)

 


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MyToDo</title>
</head>
<body>
	<a href="create.do">삽입</a><br/>
	<a href="read.do">조회</a><br/>
	<a href="update.do">갱신</a><br/>
	<a href="delete.do">삭제</a><br/>
</body>
</html>

 

**Model2 MVC 구조의 프로젝트 생성

=>todo 작업이라고 가정

=>요청은 4개라고 가정(select, insert, update, delete)

 

1.Dynamic Web Project web.xml 파일을 포함하도록 생성

 

2.servlet-api.jar 파일을 프로젝트의 WebContent/WEB-INF/lib 디렉토리에 복사

 

3.시작화면으로 사용할 index.jsp 파일을 WebContent 디렉토리에 생성

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MyToDo</title>
</head>
<body>
	<a href="create.do">삽입</a><br/>
	<a href="read.do">조회</a><br/>
	<a href="update.do">갱신</a><br/>
	<a href="delete.do">삭제</a><br/>
</body>
</html>

 

4. DTO로 사용할 클래스를 생성

    => 업무별로 패키지를 별도로 생성하여 배치

    => 모바일이나 spring web에서는 패키지 이름을 3 level 이상으로 설정

        - 회사 도메인의 역순이나 자신의 이메일 역순을 적고 업무명으로 패키지를 생성

package kr.co.pk.todo.domain;

public class ToDo {
	
}

 

5. Repository에 해당하는 클래스를 생성 - 싱글톤 패턴

    => 이름은 대부분 

package kr.co.pk.todo.repository;

public class ToDoDao {
	// 싱글톤 패턴으로 만들기 위한 코드
	// 서버를 생성하는 프레임워크에서는 아래 코드를 프레임워크가 삽입
	private ToDoDao() {
	}

	private static ToDoDao toDoDao;

	public static ToDoDao sharedInstance() {
		if (toDoDao == null) {
			toDoDao = new ToDoDao();
		}
		return toDoDao;
	}

	public void create() {
		System.out.println("DAO에서 데이터 저장");
	}
	
	public void read() {
		System.out.println("DAO에서 데이터 가져오기");
	}
	
	public void update() {
		System.out.println("DAO에서 데이터 수정");
	}
	
	public void delete() {
		System.out.println("DAO에서 데이터 삭제");
	}
}

 

6. Service 클래스를 생성

    => Service는 템플릿 메소드 패턴과 싱글톤 패턴을 적용

    => 인터페이스를 만들고 클래스를 구현

    => Dao를 가져다가 사용

    => 이름은 업무명Service, 업무명ServiceImpl

 

7. Controller 생성

    => Controller는 서블릿으로 생성

    => 싱글톤으로 만들어야 하는데 개발자가 코드를 작성할 필요가 없음

        - Servlet은 WAS가 인스턴스를 만들 때 1개만 생성하여 관리

    => url 패턴을 do 확장자를 처리하도록하고 index.html을 처리하도록 작성

        - index.html을 처리하지 않으면 시작페이지는 Controller에 오지 않게 됨

        - 모든 요청은 Controller를 거치도록 만들어야 함

        - 이처럼 Controller가 Entry Point가 되도록 하는 것을 FrontController 패턴이라고 함

 

8. 웹 서버에서의 요청 처리(숙지)

    => html, jsp에서 요청 -> Controller -> Service -> Dao -> Database -> Dao -> Service -> Controller -> View

    => 어떤 경우에는 Controller에서 바로 View로 가기도 함 : 단순 페이지 이동

    => Dao가 생략되는 경우도 있음 : 데이터베이스 작업이 없는 단순한 업무처리

    => Controller에서 View로 가지 않고, 다시 Controller를 거쳐서 View로 가기도 함

        - redirect의 경우 바로 View로 가지않고 Controller에게 다시 요청하여 결과 페이지로 포워딩

    => 웹 브라우저에 출력을 할 때는 View가 jsp나 html이 되는 것

        - 타 프로그램에서 서버에 요청하는 경우 View가 json이나 xml이 되는 것

 

**Filter

    => AOP(Aspects Of Programming - 관점지향 프로그래밍) : 애플리게이션을 구현하다보면 Business Logic(업무 처리

       내용)과 Common Concern(공통 관심사항)이 같이 수행되어야 하는 경우가 많음

        - 하나의 메소드에 기능이 다른 코드를 같이 작성하는 것은 가독성을 떨어뜨림

        - 메소드를 분리, 작성후 호출하는 방식을 사용할 수 있지만 Java Web Programming에서 아예 별도의 클래스에

         메소드를 만든후 설정에서 호출하도록 만들수 있음

        - 빌드시 설정 내용을 가지고 클래스 코드를 수정

        - 실제 만들어진 클래스에는 순서대로 호출하는 코드가 보임

    => Java Web에서는 AOP를 Filter와 Listener를 이용하여 구현하고 Spring에서는 Interceptor와 AOP를 이용하여 구현

    => AOP 사용시 Business Logic과 Common Concern이 같이 존재하지 않아 가독성이 높아지고 유지보수에 유리

1. Listener

    => 이벤트가 발생했을 때, 이벤트를 처리해주는 객체

    => Java EE에서는 웹 애플리케이션이 시작, 종료시와 세션 생성, 소멸시 호출 메소드를 소유한 리스너가 각각 존재

    => 애플리케이션이 시작될 때는 나중에 필요한 자원들을 전부 생성

        - 애플리케이션이 종료될 때는 메모리 정리 작업 수행

    => 세션이 생성, 소멸될때는 주로 접속한 세션의 개수를 더하거나 빼는 작업을 하여 현재 접속중인 세션수 확인

    => 세션 소멸시 호출되는 메소드는 브라우저를 종료하거나 컴퓨터를 강제로 종료하면 호출되지 않음

        - 웹 클라이언트 제작시 브라우저 종료직전(beforeunload)이벤트처리 핸들러에서 ajax로 서버에 종료를 알려야 함

 

2. Filter

    => 클라이언트의 요청이 Controller에 전달 전, Controller가 처리 후에 수행 할 작업을 작성할 수 있는 인터페이스

  1) 메소드

    => init : 초기화 메소드

    => destroy : 소멸될 때 호출되는 메소드

    => doFilter : Controller에게 전달 전이나 처리 후에 호출되는 메소드(이 메소드를 재정의하여 수행할 일들을 작성)

        - chain.doFilter()를 호출하는 구문 앞에 기재 : Controller 처리 전, 뒤에 기재 : 처리 후, 미호출 : 요청을 비처리

  2) URL 패턴 적용

    => 상단에 Annotation을 이용하여 적용할 수 있고, web.xml파일에 설정 가능

 

3. Authentication Filter 만들기

    => Authentication(인증) : 로그인 여부에 따라 자원의 사용여부를 결정

    => Authorization(인가) : 권한여부에 따라 자원의 사용여부 결정(User 테이블 권한을 저장가능한 칼럼이 있어야 함)

 

    => 쓰기 요청을 할 때 로그인 여부를 확인하여 로그인이 되어 있지 않으면 로그인 페이지로 이동하도록 하기

 

1) index.jsp 파일을 수정

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MyToDo</title>
</head>
<body>
	<a href="create.do">삽입</a><br/>
	<a href="read.do">조회</a><br/>
	<a href="update.do">갱신</a><br/>
	<a href="delete.do">삭제</a><br/>
	
	<%@ taglib prefic="c" uri="http://java.sun.com/jsp/jstl/core"%>
	<c:if test="${ id == null }">
		<a href="login.do">로그인</a></br>
	</c:if>
	<c:if test="${ id != null }">
		<a href="logout.do">로그아웃</a></br>
	</c:if>
	<a href="write.do">글쓰기</a><br/>
</body>
</html>

 

  2) WebContent 디렉토리에 user 디렉토리를 작성하고, login.jsp 파일 생성

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인</title>
</head>
<body>
	<form action="login.do" method="post" id="loginform">
		아이디<input type="text" size="30" name="id"
		id="id" /><br/>	
		비밀번호<input type="password" size="30" name="pw"
		id="pw" /><br/>	
		<input type="submit" value="로그인" />
		<p id="loginbtn">로그인</p>
	</form>
	<script>
		document.getElementById("loginbtn")
			.addEventListener("click", function(event){
			document.getElementById("loginform").submit();
		})
	</script>
</body>
</html>

 

  3) WebContent 디렉토리에 board 디렉토리를 만들고 write.jsp파일을 생성하고 작성

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	이 페이지는 로그인 한 유저만 사용할 수 있습니다.
</body>
</html>

 

  4) jstl.jar 파일을 WebContent/WEB-INF/lib 디렉토리에 복사

 

  5) Controller 클래스에 요청 처리하는 부분을 추가
    =>로그인 페이지로 이동하는 코드와 글작성 페이지로 이동하는 코드를 doGet 메소드에 추가

case "/login.do":
	//GET 요청은 입력 페이지로 이동하고 
	//POST 요청은 작업을 처리
	if("GET".equals(method)) {
		dispatcher = 
			request.getRequestDispatcher("user/login.jsp");
		dispatcher.forward(request, response);
	}else {
				
	}
	break;
	case "/write.do":
		dispatcher = 
			request.getRequestDispatcher("board/write.jsp");
		dispatcher.forward(request, response);
		break;

 

  6) 로그인화면에서 입력을 하고 로그인 요청을 처리하는 코드를 작성

    => 작업을 수행해야 할 때는 데이터베이스 사용여부 확인 - 데이터베이스 사용한다면 Dao 메소드를 만들어 구현

    => Service 인터페이스에 처리해줄 메소드를 선언

        - 리턴타입은 void, 매개변수는 HttpServletRequest, HttpServletResponse로 설정하는데 request만 선언하기도 함

//로그인 처리
public void login(HttpServletRequest request, HttpServletRequest response);

    => ServiceImpl 클래스에 처리해줄 메소드를 구현

case "/login.do":
	//GET 요청은 입력 페이지로 이동하고 
	//POST 요청은 작업을 처리
	if("GET".equals(method)) {
		dispatcher = 
			request.getRequestDispatcher("user/login.jsp");
		dispatcher.forward(request, response);
	}else {
		//작업 수행
		toDoService.login(request, response);
		//결과 페이지로 이동 - 로그인 처리는 마지막이 리다이렉트
		//시작 페이지로 이동
		response.sendRedirect(contextPath);
	}
	break;

 

  7) 로그아웃 처리를 위한 코드를 Controller 클래스의 doGet 메소드에 작성 

case "/logout.do":
	//로그아웃은 세션을 초기화
	session.invalidate();
	response.sendRedirect(contextPath);
	break;

 

  8) write.do 요청이 오면 동작하는 필터를 생성하고 로그인이 되어 있지 않으면 로그인 페이지로 이동하는 코드를 작성

//AuthenticationFilter.java
package kr.co.pk.todo.filter;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@WebFilter("/write.do")
public class AuthenticationFilter implements Filter {

    public AuthenticationFilter() {
        // TODO Auto-generated constructor stub
    }

	public void destroy() {
		// TODO Auto-generated method stub
	}

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		//주의점 : 매개변수인 request가 HttpServeltRequest가 아니라서 강제 형 변환을 하여 사용
		HttpServletRequest req = (HttpServletRequest)request;
		
		//세션에서 ID를 가져옴
		String id = (String)req.getSession().getAttribute("id");
		
		//로그인이 되어있지 않다면
		if(id == null) {
			HttpServletResponse rep = (HttpServletResponse)response;
			//이전 요청을 세션에 저장
			req.getSession().setAttribute("path", req.getRequestURI());
			System.out.println(req.getRequestURI());
			rep.sendRedirect("login.do");
			
		}else {
			//원래 요청을 처리
			chain.doFilter(request, response);
		}

	}

	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
	}

}

    => 이전 위치로 이동하도록 ToDoController.java의 case "/login.do" 부분 수정

case "/login.do":
	//GET 요청은 입력 페이지로 이동하고 
	//POST 요청은 작업을 처리
	if("GET".equals(method)) {
		dispatcher = request.getRequestDispatcher("user/login.jsp");
		dispatcher.forward(request, response);
	}else {
		//작업 수행
		toDoService.login(request, response);
		//결과 페이지로 이동 - 로그인 처리는 마지막이 리다이렉트
		//이전에 요청한 주소가 있는 지 확인
		String path = (String)session.getAttribute("path");
		if(path == null)
			response.sendRedirect(contextPath);
		else {
			//이전 요청 주소 삭제
			session.removeAttribute("path");
			response.sendRedirect(path);
		}
	}
	break;