ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Servlet, 과도기 MVC
    JAVA 2021. 7. 25. 14:15

     

    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;
    
    @WebServlet("/MyServlet") // 이 웹서버에 /MyServlet 요청시 이 Servlet 이 반환
    //@WebServlet("/") // 이 웹서버에 아무거나 요청해도 이 Servlet 이 반환.
    public class MyServlet extends HttpServlet {
    
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		System.out.println("도네");
    	}
    
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	}
    
    }

    eclipse 에서 run 시키면 get 방식으로 요청한 거라서 doGet이 호출된다.

    GET, POST < = > HTTP (프로토콜 = 약속)

    GET = url 에 데이터를 저장 = > HTTP 을 토대로 html 파일을 반환

    POST = url 이 아닌 head 에 데이트를 저장(직접 확인 불가) = > HTTP 을 토대로 HTML 파일을 반환

     


    Server 의 server.xml 을 살펴보면 : 도메인원리

          <Context docBase="board_member" path="/board_member" reloadable="true" source="org.eclipse.jst.jee.server:board_member"/>
          <Context docBase="jstl" path="/jstl" reloadable="true" source="org.eclipse.jst.jee.server:jstl"/>
          <Context docBase="AboutSerlvet" path="/AboutSerlvet" reloadable="true" source="org.eclipse.jst.jee.server:AboutSerlvet"/>

    요청한 URL 확인하기

    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		System.out.println(request.getRequestURL());	// 요청한 전체 URL
    		String 요청작업 = request.getRequestURI().substring("/AboutSerlvet/".length());
    		
    		System.out.println(request.getRequestURI());	// 요청한 "프로젝트/요청작업명" URL
    		System.out.println(요청작업);					// 위에서 프로젝트명을 잘랐으니 "요청작업명" 만 출력
    	}
    /* 출력
    http://localhost:8090/AboutSerlvet/MyServlet
    /AboutSerlvet/MyServlet
    MyServlet
    */


    >> MyServlet.java (이 Servlet 에서 여러 작업을 다 할 수 있다.)

    //FrontController
    @WebServlet("/") // 이 웹서버에 아무거나 요청해도 이 Servlet 이 반환.
    public class ForntController extends HttpServlet {
    
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		
    		IControl control = null;
    		// 요청과 컨트롤 객체 매핑
    		String 요청작업 = request.getRequestURI().substring("/AboutSerlvet/".length());
    		
    		if(요청작업.equals("addboard")) {	//게시물등록
    			control = new 게시물등록();
    		}
    		else if(요청작업.equals("prepareboard")) {	//게시물등록준비
    			control = new 게시물등록준비();
    		}
    
    		// 해당 컨르롤 요청처리
    		String 지정된뷰명 = control.process(request,response);
    		System.out.println(지정된뷰명);
    		// forward
    		RequestDispatcher rd = request.getRequestDispatcher(ViewResolver.getJspViewName(지정된뷰명));
    		rd.forward(request, response);
    	}
    
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		doGet(request,response);
    	}
    
    }

     

    >> IControl.java (interface)

    public interface IControl {
    	// view 이름 요청처리 // 입력: 일단 넓게 일반적으로 요청객체로 대신
    	String process(HttpServletRequest request, HttpServletResponse response);
    }

    >> 게시물등록준비.java

    public class 게시물등록준비 implements IControl{
    
    	@Override
    	public String process(HttpServletRequest request, HttpServletResponse response) {
    		// 요청
    		
    		// 업무
    		System.out.println("등록 업무 규칙 검사");
    		// 경로지정
    		
    		return "게시물등록창";
    	}
    }

    >> 게시물등록창.jsp

    <body>
    	<h1>게시물목록</h1>
    	<form action="addboard" method="post">
    	제목 <input type="text" name="title"/>
    	내용 <input type="text" name="contents"/>
    	<input type="submit" value="등록하기"/>
    	</form>
    </body>

    >> 게시물등록.java

    public class 게시물등록 implements IControl{
    
    	@Override
    	public String process(HttpServletRequest request, HttpServletResponse response) {
    		// 요청
    		String 제목 = request.getParameter("title");
    		String 내용 = request.getParameter("contents");
    		// 업무
    		
    		System.out.println("게시물DAO를 통해 save()");
    		// 경로지정
    		request.setAttribute("title", 제목);
    		return "게시물등록결과통보";
    	}
    }

    >> 게시물등록결과통보.jsp

    <body>
    	${title} 가 등록되었습니다.
    </body>

    Servlet 

    Client
    - > Web Server(이미지나 html 확장자 파일은 WebServer 에서 처리)
    -> JSP Server ( JSP 파일 요청시 JSP Server 에서 처리)

    1. JSP - Servlet 관계

    JSP Server : Servlet 클래스가 Tomcat 안에서 작동하여 아래처럼 실행.
    JSP -(java코드)- > java -(컴파일)- > class -> HTML
    java 코드는 Servlet 클래스를 이용하여 작성되어 있는데
    원래 JSP 가 아니라 Servlet 이 먼저 나왔으며
    JSP 전에는 Servlet 을 이용해 java 코드로 직접 작성했었다.

    2. Static Web 과 Dynamic Web 의 관계

    Static Web = Web Server
    Dynamic Web = Web Server + JSP Server(Tomcat)
    Maven Web = Dynamic Web 이지만 Library 관리를 Maven 이 알아서 해준다는 차이점만 있음

    3. Dynamic Web 과 Maven Web 의 Server 작동원리

    Dynamic Web 의 root context 폴더 = WebContent ( 이름 변경 가능 )
    Maven Web 의 root context 폴더 = webapp ( 이름 변경 가능 )
    root context 폴더는 그 하위의 META-INF, WEB-INF ( 이름 변경 불가능 ) 의 폴더들을 먼저 읽으라고 단위를 만들어 놓은 폴더일 뿐이다.
    (Server에서 root context 폴더 아래에 저 2폴더가 있는지 찾아서 읽는다.)

    Serlvet=FrontController ( 요청과 컨트롤 짝지음 ) - Control ( 클래스 )
    객체 매핑

    과도기 MVC

    Serlvet=FrontController ( 요청과 컨트롤 짝지음 ) - Control ( 메서드 )
    메서드 매핑 (FrontController 가 Spring 언어로 바뀐다.)

    Spring MVC // Spring 나갈 때 이제 이 모델로 바꾼다.

    1. 디렉터리(=서블릿매핑명) 을 "/" 로 웹서버에서 아무거나 요청해도 이 Servlet이 반환되도록 만든다.
    2. 요청작업명을 따로 잘라와 맞는 작업명을 if문으로 각각 나누어 작성한다
    3. 클래스를 만들어 요청작업에 맞게 메서드를 만든다. (요청작업마다 여러개 만들어진다.)
    실제 작업하는 클래스인 것이다. ( 업무(control + model) 를 한다 )
    4. 서블릿에서는 그 클래스에게 작업을 시킨다. (request,response 를 매개값으로 준다.)
    즉 서블릿은 대리시킬 뿐 실제 작업하지 않는다. ( 요청만 받고 업무하는 클래스와 메서드를 짝지어 주기만 한다. )

    Control (클래스)

    요청 - 업무 - 경로지정

    요청: 받는 요청값들이 전부 다를 수 있다.
    - 메서드에서 FrontController 에게 받은 request, response 로 요청 받는다.
    // 단, 이는 업무제한을 걸 수 없어 위험한 방법이다.
    ex) 제목, 내용만 받고 오고 싶지만 request 가 다른정보도 가지고 있다면 다른것도 가져와버린다.
    제목, 내용만 매개로 받아오도록 메서드를 수정하면 FrontController 에서 추출하는 작업을 해야하고, 그러면 일관성이 떨어진다.
    이를 Spring 에서는 해결했다.
    업무: 요청값들이 다르니 하는 업무도 다를 수 있다.
    경로지정: 경로를 지정하는 forward 코드는 똑같다.
    - 반복코드가 되버린다.
    // 그래서 메서드는 경로를 결과값으로 반환하고, FrontController 에서 if문 끝나고 forward 를 시키게 한다.
    시나리오
    1. 요청페이지는 모두 MyServlet.java 를 응답받는다 (매핑명이 "/" 이니까) (요청)
    2. 응답받은 MyServlet.java 에서 요청명을 따로 추출(substring()) 하여 if 문에서 같은 이름의 요청명을 찾는다. (업무)
    3. 각 요청작업에 맞는 클래스들을 미리 만든 인터페이스형 참조변수에 new 생성자로 생성한다.
    4. 구현한 process() 메서드를 작동시켜 결과값으로 들어갈 뷰이름을 얻는다.
    5. forward 로 그 뷰에 넘어간다. (뷰)
    6. 뷰에서 submit 해서 active 주소로 넘어갈 때 다시 MyServlet.java 를 응답받는다. (요청)
    7. MyServlet.java 에서 요청명을 따로 추출하여 if문에서 같은 이름의 요청명을 찾는다.
    8. 요청작업을 할 클래스를 생성하고 다시 메서드를 실행시키는데 submit된 값을 가지고 있는 MyServlet.java의 request가
    매개값으로 들어가니 메서드에서 그 값을 추출하고 저장가능하게 된다. (업무)
    9. 이를 반복한다.

    'JAVA' 카테고리의 다른 글

    ModelAndView  (0) 2021.07.25
    MVC 3 Tier,인터페이스정의서,AJAX-JSON사용,BLOB(image)  (0) 2021.07.25
    MVC모델2, JSTL  (0) 2021.07.25
    MVC모델이란  (0) 2021.07.25
    ConnectionPool,ViewResolver  (0) 2021.07.25

    댓글

Designed by Tistory.