ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • JSP 피피티 06강 컨트롤러 추상화
    JSP 피피티 2020. 8. 21. 13:27

    Controller 준비

    (1)BaseController.java

    package study.jsp.model2.helper;
    
    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;
    
    /**
     * Servlet implementation class BaseController
     */
    @WebServlet("/BaseController")
    public class BaseController extends HttpServlet {
    	private static final long serialVersionUID = 1L;
           
        /**
         * @see HttpServlet#HttpServlet()
         */
        public BaseController() {
        	//실행되는 주체를 확인하기 위해서 클래스 이름을 콘솔에 줄력한다.
        	String className = this.getClass().getName();
        	System.out.println(className); // 생성자 안에서 자기클래스 이름을 출력하게 해놈
        }
    
    	/**
    	 * pageInit()을 추가하고, doGet()과 doPost()에서 이 메서드를 호출한다.
    	 * Get방식 요청이 들어오면 실행된다.
    	 */
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		// 공통처리 메서드로 제어를 이동시킨다.
    		this.pageInit(request, response);
    	}
    
    	/**
    	 * Post방식 요청이 들어오면 실행된다.
    	 */
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		// 공통처리 메서드로 제어를 이동시킨다.
    		this.pageInit(request, response);
    	}
    	
    	/**
    	 * Get, Post 방식에 상관없이 공통 처리되는 메서드
    	 * @param request -JSP request 내장 객체
    	 * @param response -JSP respond 내장 객체
    	 */
    	private void pageInit(HttpServletRequest request, HttpServletResponse response)
    		throws ServletException, IOException{
    		
    		//페이지 형식 지정하기
    		response.setContentType("text/html; charset=utf-8");
    		//파라미터 처리 형식 지정하기
    		request.setCharacterEncoding("utf-8");
    		
    		//View의 이름
    		String view = doRun(request, response);
    		
    		//획득한 View가 존재한다면 화면 표시
    		if(view != null){
    			//View를 생성ㅎ나다.
    			view="/WEB-INF/views/" + view + ".jsp";
    			RequestDispatcher dispatcher = request.getRequestDispatcher(view);
    			dispatcher.forward(request, response); //이 경로의 파일을 view로 연다.
    		}
    	}
    	
    }
    

    -위의 코드를 보면 어떤 방식(Do, Post)으로 request가 들어와도 pageInit()메서드로 요청을 처리한다.

     왜? GET, POST 따로 하는게 번거로우니까 한번에 한다. 

     

    -동작중인 클래스를 파악하기 위하여 현재클래스의 이름을 콘솔에 출력하도록 했다. 생성자에서.

     

    VIew페이지 준비

    hello.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    <%@ page trimDirectiveWhitespaces="true" %>
    <!doctype html>
    <html>
    <head>
        <meta charset="UTF-8" />
        <title>Insert title here</title>
    </head>
    <body>
        <h1>Hello Base Controller</h1>
    </body>
    </html>

    (1)BaseController.java을 실행하면 hello.jsp가 실행되고 이클립스 콘솔에 study.java.helper.BaseController라고 요청을 받고 처리한 서블릿의 이름이 뜬다. 

     

    (2)BaseController.java

    package study.jsp.model2.helper;
    
    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;
    
    /**
     * Servlet implementation class BaseController
     */
    @WebServlet("/BaseController")
    public abstract class BaseController extends HttpServlet {
    	private static final long serialVersionUID = 1L;
           
        /**
         * @see HttpServlet#HttpServlet()
         */
        public BaseController() {
        	//실행되는 주체를 확인하기 위해서 클래스 이름을 콘솔에 줄력한다.
        	String className = this.getClass().getName();
        	System.out.println(className); // 생성자 안에서 자기클래스 이름을 출력하게 해놈
        }
    
    	/**
    	 * pageInit()을 추가하고, doGet()과 doPost()에서 이 메서드를 호출한다.
    	 * Get방식 요청이 들어오면 실행된다.
    	 */
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		// 공통처리 메서드로 제어를 이동시킨다.
    		this.pageInit(request, response);
    	}
    
    	/**
    	 * Post방식 요청이 들어오면 실행된다.
    	 */
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		// 공통처리 메서드로 제어를 이동시킨다.
    		this.pageInit(request, response);
    	}
    	
    	/**
    	 * Get, Post 방식에 상관없이 공통 처리되는 메서드
    	 * @param request -JSP request 내장 객체
    	 * @param response -JSP respond 내장 객체
    	 */
    	private void pageInit(HttpServletRequest request, HttpServletResponse response)
    		throws ServletException, IOException{
    		
    		//페이지 형식 지정하기
    		response.setContentType("text/html; charset=utf-8");
    		//파라미터 처리 형식 지정하기
    		request.setCharacterEncoding("utf-8");
    		
    		//View의 이름
    		String view = doRun(request, response);
    		
    		//획득한 View가 존재한다면 화면 표시
    		if(view != null){
    			//View를 생성ㅎ나다.
    			view="/WEB-INF/views/" + view + ".jsp";
    			RequestDispatcher dispatcher = request.getRequestDispatcher(view);
    			dispatcher.forward(request, response); //이 경로의 파일을 view로 연다.
    		}
    	}
    	
    	//웹 페이지 구성에 필요한 처리를 수행한 후, View의 이름을 리턴한다.
    	//이 메서드를 추상화 한다.
    	//이 클래스를 상속받는 자식 클래스는 반드시 이 메서드를 재정의 해야 한다.
    	public abstract String doRun(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException;
    }
    

    위 코드는 (1)BaseController.java에 맨 마지막 부분에 doRun이라는 추상메서드를 추가한 것이다.

    어떤 클래스가 추상메서드를 하나라도 가지고 있다면 그 클래스 또한 추상클래스가 되어야 하기때문에  abstract를 클래스에 부여했다. 

     

    잠깐!! 추상화??

    더보기

    추상화 기법은 특정 클래스를 상속받은 경우, 부모의 특정 메서드들을 무조건 재정의하도록 강제하는 기법이다. 

    특정 메서드를 재정의하도록 강제함으로써, 자식 클래스들을 작성하기 위한 가이드의 역할을 할 수 있다.

    즉, 추상화 기법은 JAVA클래스를 작성하기 위한 설계도를 소스코드 형태로 제시하는 역할을 한다.

     

    추상메서드 > 자식 클래스가 구현해야 하는 메서드의 가이드라이만 제시하기 위한 목적으로 사용되기 때문에, 선언만 가능하고 구현부가 없다. 자식 클래스들은 이 메서드를 반드시 재정의 해야한다.

     

    추상 클래스는 객체를 생성할 수 없고, 반드시 상속을 통해서만 사용될 수 있다. 즉 추상 클래스는 다른 자식 클래스를 위한 '가이드라인'의 역할을 한다. 

     

    추상 클래스는 생성자, 멤버변수, 일반 메서드 등을 포함할 수 있다.

    즉 공통 기능과 가이드라인을 모두 정의하여 다른 클래스에게 상속된다. 

    추상 클래스를 상속받는 간결한 서블릿 만들기

    HttpServelet을 상속받는 BaseController가 추상클래스이므로, BaseController를 상속받는 Hello 클래스 역시 서블릿이 된다. 부모 클래스 A를 자식 클래스 B가 상속받을 때, B는 A의 모든 멤버변수와 메서드를 자신의 것으로 상속받게된다.(private 빼고)

    BaseController가 추상클래스이기 때문에, Hello 클래스는 BaseController에 정의된 모든 메서드를 강제로 재정의 해야한다.

    Hello.java

    package study.jsp.model2.controller;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import study.jsp.model2.helper.BaseController;
    @WebServlet("/hello")
    public class Hello extends BaseController {
    
    	/**
    	 * 
    	 */
    	private static final long serialVersionUID = 6519981277847414078L;
    
    	@Override
    	public String doRun(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		String view = "hello";
    		return view;
    	}
    
    }
    

    Hello.java는 (2)BaseController.java를 상속받았기 때문에 부모 클래스의 모든 멤버변수와 메서드를 쓸수 있고 doRun()을 재정의 했다.

     

    http://localhost:8080/Hello로 요청이 들어왔을때 Hello.java서블릿에서 요청을 받는다. (2)BaseController.java를 상속받았기 때문에 부모에 정의된 doGet()/doPost()를 사용하여 처리를 pageInit()에 보내고 pageInit()안에 쓰인 doRun()을 실행해 사용한 View의 이름을 (2)BaseController.java리턴받고 View(hello.jsp)로  출력!

전설의 개발자