놀코에 오신 것을 환영합니다.

놀아보자 코드랑

KOSTA/WEB

21.06.21 - 백엔드( Back-End)- 톰캣, sevlet, MVC *중요*

놀코 2021. 6. 21. 12:46

깃허브

https://github.com/sblee1031/Kosta/tree/main/ORACLE_DB_THEOTY/Oracle_DB_project/myweb

 

sblee1031/Kosta

KOSTA_219. Contribute to sblee1031/Kosta development by creating an account on GitHub.

github.com


** 면접 질문

1. get방식, post방식

2. 페이지 이동시 forward 방식과 redirect방식의 차이에 대해서 말해봐라.

 

백엔드란?

WEB : html, css, js

WEB Sever : jsp(JAVA) - (톰캣,레진, 웹로직, 웹스피어, 제우스, Ngix), asp(VB) - IIS , php(C,Perl) - Apach

-->> IIS, Apach에서는  JAVA를 실행 시켜줄 엔진이 없다.

 

클라이언트->서버->DB

위 순으로 일을 할 수 있게 됨.

* NODE.js 사용은 예외임

Servlet 학습시 ->jsp, Spring MVC 쉽게 이해 가능

 

웹프로젝트 표준안

ex) 프로젝트명 : myback (WEB-INF : 반드시 필요한 디렉토리)

* WEB-INF(classes: 필수 디렉토리) - 같은 위치 경로 lib라이브러리( *.jar파일로 저장)

* Web.xml (웹프로젝트 정보 - 요청URL에 매핑될 서블릿(jsp))

 

이클립스 프로젝트 생성시 주의사항

꼭 Dynamic Project로 프로젝트 생성을 해야 함.

프로젝트 생성시 초기 폴더 구성

 

* 프로젝트 생성 후 서버 구동시 폴더구조 및 흐름도

톰캣에 구동시 디렉토리 정렬 흐름

 

서블릿 API ver

Dynamic Web Module에 따른 버전 차이

2.5 ver : Web.xml 필수.

4.0 ver :      -     선택사항 (사용 안할경우에는 그 일처리를 @annotation으로 처리한다.)

 

web.xml 구성

servlet-namer과 servlet-class를 매칭시켜 실행 해줌.

ex) /first 주소에서 servlet-class로 경로를 가리킴.

Sevlet 객체 요청,응답 흐름도.

destroy() 메서드 호출 시점 : 객체 소멸시 자동호출.

1. 톰캣 중지

2.서블릿 클래스 내용이 변경 될 경우.

 

웹 컨텍스트 = 웹 모듈 = 웹어플리케이션 동의어들..

톰캣을 시작하면 프로젝트별 객체가 각각 생성됨.

servletContext 객체 - 

httpServlet request 객체 / httpServlet response 객체

attr - 객체(Map타입)  /  param - 객체(Map타입)

API

web.xml 에 <context-param>을 등록시 모든 servletContext에서 공유자원 으로 사용 가능.

 <servlet>태그 하위 <init-param>으로 설정시 해당 servlet객체에서만 사용

* 주소 쿼리 스트림

요청시 전달된 자료는 request 객체에 전달됨

id=1, pwd = p1 -> httprequest로 전달되어 저장됨.

응답 후 소멸

응답 후 소멸 과정

** web.xml 파일이 수정시 톰캣 서버는 restart되어야 한다.

 

package com.day.control;

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

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class FirstServlet
 */
public class FirstServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public FirstServlet() {
        super();
        System.out.println("FirstServlet객체생성됨");
//        //context-param얻기
//        ServletContext sc = getServletContext();
//        String devName = sc.getInitParameter("Developer");
//        System.out.println("책임 개발자 :" + devName);
    }


	/**
	 * @see Servlet#init(ServletConfig)
	 */
	public void init(ServletConfig config) throws ServletException {
		System.out.println("FirstServlet의 init() 메서드 호출");
		super.init(config); //servletcontext객체 참조 작업 해줌.
		//context-param얻기
	      ServletContext sc = getServletContext();
	      String devName = sc.getInitParameter("Developer");
	      System.out.println("책임 개발자 :" + devName);
	      String realPath = sc.getRealPath("logo.jpg");
	      System.out.println("logo.jpg의 실제경로 :"+realPath);
	      File file = new File(realPath);
	      if(!file.exists()) {
	    	  System.out.println("logo.jpg 파일이 없습니다");
	      }
	      //servlet의 init-param값 얻기
	      String fileName=this.getInitParameter("fileName");
	      System.out.println("FistServlet에서만 사용할 수 있는 파라메터 fileName:" + fileName);
	}

	/**
	 * @see Servlet#destroy()
	 */
	public void destroy() {
		System.out.println("FirstServlet의 destroy() 메서드 호출");
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		System.out.println("FirstServlet의 doGet() 메서드 호출");
		String idValue = request.getParameter("id");
		String pwdValue =request.getParameter("pwd");
		
		System.out.println("요청전달데이터 id :" +idValue + ", pwd : "+pwdValue);
		String[] cArr = request.getParameterValues("c"); // 전달이 아예 되지 않을 경우를 준비해야함.
		if(cArr != null) {
			for(String cValue : cArr) {
				System.out.println("요청전달 데이터 C:" + cValue);
			}
		}
		
//		http://localhost:8888/myback/first?id=id1&pwd=p1&c=c1&c=c2
//		http://localhost:8888/myback/first?id=id1&pwd=p1  ->cArr은 null / nullpointException 발생
//		http://localhost:8888/myback/first?id=id1- > pwValue는 null
//		http://localhost:8888/myback/first?id=&pwd=p1 ->idValue는 ""
		
		String contextPath = request.getContextPath();
		System.out.println(getServletContext().getContextPath());// getContextPath(); 와 같음.
		String uri = request.getRequestURI();
		StringBuffer url = request.getRequestURL();
		System.out.println("contextPath:" + contextPath); //  /myback
		System.out.println("uri : " + uri); //  /myback/first
		System.out.println("url : " + url); // http://localhost:8888/myback/first
		String servletPath = request.getServletPath();
		System.out.println("servletPath : "+servletPath);  // servletPath: /first
		
	   response.setContentType("text/html;charset=utf-8");// 응답형식은 MIME 표준방식을 따른다
	   PrintWriter out = response.getWriter();//응답 출력스트림을 얻기
	   out.print("<html>");
	   out.print("<body>");
	   out.print("<h1>응답결과입니다<h1/>");
	   out.print("</body>");
	   out.print("</html>");

		
		

	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("FirstServlet의 doPost() 메서드 호출");		
	}

}

 

 

Servlet이란

서버에서 실행되는 특수 application / main메서드가 없는 상태.

서브릿 자체 내에서 요청과 응답을 진행함.

Model1 구조

 

 

* 요청과 응답을 분리한 Model2 구조 (MVC 디자인 패턴 구조) 

Model2 구조

 

 

MoveServlet.java

* 페이지 이동

RequestDispatcher _ forward() 메서드

* forward 메서드는 객체 생성 확인을 하지 않고 그냥 clear함.

RequestDispatcher _ include 메서드

* firstSevlet 객체를 갔다가, 다시 MoveServlet 으로 돌아 옴.

 

페이지 이동 forward메서드 + include메서드

 

* redirect();

redirect 요청시 구동

 

forward, include, redirect 전체 흐름도

forward, include, redirect 전체 흐름도

 

package com.day.control;

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

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

/**
 * Servlet implementation class MoveServlet
 */
public class MoveServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private void show(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
		//응답형식 지정: text/html
		response.setContentType("text/html;charset=UTF-8");
		
		//응답출력스트림 얻기
		PrintWriter out = response.getWriter();
		out.print("<html>");
		out.print("<body>");
		out.print("<ol>");
		out.print("<li><a href=\"./move?opt=forward\">포워드</a></li>");
		out.print("<li><a href=\"./move?opt=include\">인클루드</li>");
		out.print("<li><a href=\"./move?opt=redirect\">리다이렉트</li>");
		out.print("</ol>");
		out.print("</body>");
		out.print("</html>");
		
	}
	private void forward(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//응답형식 지정: text/html
		response.setContentType("text/html;charset=UTF-8");
		
		//응답출력스트림 얻기
		PrintWriter out = response.getWriter();
		out.print("before forward");
		String path = "first";
		RequestDispatcher rd = request.getRequestDispatcher(path); // first 객체가 있는지 확인한다.
		rd.forward(request, response); //완전 이동
		out.print("after forward");
	}
	private void include(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=UTF-8");
		
		//응답출력스트림 얻기
		PrintWriter out = response.getWriter();
		out.print("before include");
		String path = "first";
		RequestDispatcher rd = request.getRequestDispatcher(path);
		rd.include(request, response); // 다른곳으로 이동했다가 다시 돌아옮
		out.print("after include");
	}
	private void redirect(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=UTF-8");
		
		PrintWriter out = response.getWriter();
		out.print("before include");
		
		String location = "first";
		response.sendRedirect(location);
		
		out.print("after include");
	}
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//요청전달 데이터(이름:opt)가 전달안된 경우
		String opt = request.getParameter("opt");
		if(opt == null || opt.equals("")) {
			show(request, response);
		}else if(opt.equals("forward")) {
			forward(request, response);
		}else if (opt.equals("include")) {
			include(request, response);
		}else if(opt.equals("redirect")) {
			redirect(request, response);
		}
	}

}

 

LoginServlet.java  
요청사항.

 

 

package com.day.control;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.day.exception.FindException;
import com.day.service.CustomerService;

/**
 * Servlet implementation class LoginServlet
 */
public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.addHeader("Access-Control-Allow-Origin", "*"); //보안 정책 허용.

		//1. 요청전달데이터 얻기
		String id = request.getParameter("id");
		String pwd = request.getParameter("pwd");
		ServletContext sc =getServletContext();
		
		CustomerService.envProp = sc.getRealPath(sc.getInitParameter("env"));
		CustomerService service = CustomerService.getInstance();
		//2. 비지니스로직 호출
		String path = "";
		try {
			service.login(id, pwd);
			//3. 성공
			path = "success";
		} catch (FindException e) {
			e.printStackTrace();
			//4. 실패
			path = "fail";
		}
		//5. 페이지 이동
		RequestDispatcher rd = request.getRequestDispatcher(path);
		rd.forward(request, response);
		
	}

}