seoyoung.dev

Servlet/Lifecycle/Response-Request객체 활용 본문

WEB/Javascript

Servlet/Lifecycle/Response-Request객체 활용

seo-0 2019. 9. 9. 15:33

< 부스트코스 웹 프로그래밍 PJT-1 을 위한 백엔드 강좌를 참고하였습니다. >

 

* 개발환경 설정 

Apache Tomcat 다운로드 및 설치

아파치 톰캣은 http://tomcat.apache.org 에서 다운로드 받을 수 있습니다.

-> Tomcat 8 설지 

 

Apach Tomcat 실행

아파치 톰캣 설치 폴더 아래에 있는 bin폴더를 보면 확장자가 bat인 윈도우용 배치파일과 확장자가 sh인 쉘스크립트(shell script)파일이 있는 것을 확인할 수 있습니다.
(쉘스크립트 파일은 linux나 맥 운영체제에서 실행 가능한 파일입니다.)
윈도우 사용자라면 startup.bat파일을 더블 클릭하여 실행하고, 맥 운영체제나 linux를 사용하는 사용자는 startup.sh을 더블 클릭하여 실행합니다.

+ eclipse 


 

* servlet 

dynamic web project 를 이클립스에서 생성, 해당 프로젝트에서 servlet 클래스 작성,

작성된 servlet은 이클립스 내부에서 설정한 runtime( 톰캣 에 의해서 동작 ),

웹 브라우저를 이용해서, 톰캣 서버에 url 요청을 보내고, servlet 클래스가 실행되는 결과를 웹 브라우저로 확인 가능 

} //TIL 

- 자바 웹 어플리케이션 : WAS 에 설치되어 동작하는 어플리케이션 ( HTML, CSS, 자바 로 구성되는 클래스 )

 

* 자바 웹 어플리케이션 폴더 구조 

LIB 폴더 : 각종 자료 파일 저장, classes 폴더 : 작성된 자바 클래스들 

서블릿 이란, 웹프로그래밍에서 클라이언트의 요청을 처리하고, 그 결과를 다시 클라이언트에게 전송하는 Servlet클래스의 구현 규칙을 지킨 자바 프로그래밍 기술이다. 

 - html을 사용하여 요청에 응답한다. 

 - java thread 를 이용하여 동작한다. 

 - http 프로토콜 서비스를 지원하는 클래스를 상속받는다. 

( 일반적으로 웹서버는 정적인 페이지만 제공하므로, 동적인 페이지를 제공하기 위해서 웹서버는 다른 곳에 요청하여 동적인 페이지를 작성해야 한다. 이때, 웹서버가 동적인 페이지를 제공할 수 있도록 도와주는 어플리케이션이 서블릿이다.)

 

* servlet 작성 방법 - 3.0 spec 이상 
package examples;

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;

/**
 * Servlet implementation class TenServlet
 */
@WebServlet("/TenServlet") //어노테이션//urlmapping부분 
public class TenServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public TenServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		// 요청 위한 객체, 응답위한 객체 두개 생성 
	response.setContentType("text/html;charset=utf-8"); 
    //response 객체에 응답할 것이 text 인지 알려주자 
	PrintWriter out = response.getWriter(); 
    //response 객체의 getwriter 메소드는 printwriter 객체를 리턴 받을 수 있다. 
	out.print("<h1> 1부터 10까지 출력.</h1>");
	for(int i=0;i<10;i++) {
		out.print(i+"<br>");
	}
	out.close();
		
	}
}

 


* servlet 의 생명 주기 
...더보기
package examples;

import java.io.IOException;
import javax.servlet.ServletConfig;
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 LifecycleServlet
 */
@WebServlet("/LifecycleServlet")
// 해당 url로 클라이언트가 서버에게 요청 -> 서버는 url 매핑은 LifecycleServlet이라는 정보를 알아낸다.
public class LifecycleServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public LifecycleServlet() {
    	//해당 클래스가 메모리에 존재하는지 체크 -> 최초 호출 : 생성 -> 생성자 메소드 호출 
        System.out.println("lifecycleservice 생성!");
    
    }

	/**
	 * @see Servlet#init(ServletConfig)
	 */
	public void init(ServletConfig config) throws ServletException {
		// 
		System.out.println("init test 호출");
	}

	/**
	 * @see Servlet#destroy()
	 */
	public void destroy() {
		//서블릿 내용이 수정되면, 메모리에 올라가있는 서블릿 객체는 더이상 사용 불가 
		//-> destroy() 호출 -> 브라우저에서 다시 호출하면 새로운 객체를 생성, init, service 한다. 
		System.out.println("destroy 호출");
	}

	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 초기 생성 후, 새로고침이나  새로 요청하는 경우는 service 메소드만 계속호출 된다. 
		//서블릿은 서버에 서블릿 객체를 여러개 만들지 않으므로, 
		// 요청이 여러번 들어오면, 실제 요청된 객체가 메모리에 있는지 없는지만 확인해서
		//있으면 service 만 요청 
		System.out.println("service 호출 ");
	}
}

< LifecycleServlet > 

- httpservlet 의 3가지 메소드를 오버라이딩 { init, service, destroy }

WAS 는 서블릿 요청을 받으면, 메모리에 해당 서블릿이 있는지 확인 -> 메모리에 없으면, init() 실행, 메모리에 있으면, service()실행. 웹 어플리케이션이 갱신되거나 WAS 가 종료되는 경우에만 destroy() 실행 

- service() 

: httpservlet의 service 메소드 이미 템플릿 메소드 패턴으로 구현

- 클라이언트 요청이 GET 이면, doGet(request, response) 호출 

- 클라이언트 요청이 POST 일 경우에는, doPost(request, response) 호출 


* service 대신 doGet, doPost
  • HttpServlet의 doGet(request, response)메소드 오버라이딩
  • HttpServlet의 doPost(request, response)메소드 오버라이딩
...더보기

 

package examples;

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

import javax.servlet.ServletConfig;
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 LifecycleServlet
 */
@WebServlet("/LifecycleServlet")
// 해당 url로 클라이언트가 서버에게 요청 -> 서버는 url 매핑은 LifecycleServlet이라는 정보를 알아낸다.
public class LifecycleServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public LifecycleServlet() {
    	//해당 클래스가 메모리에 존재하는지 체크 -> 최초 호출 : 생성 -> 생성자 메소드 호출 
        System.out.println("lifecycleservice 생성!");
    
    }

	/**
	 * @see Servlet#init(ServletConfig)
	 */
	public void init(ServletConfig config) throws ServletException {
		// 
		System.out.println("init test 호출");
	}

	/**
	 * @see Servlet#destroy()
	 */
	public void destroy() {
		//서블릿 내용이 수정되면, 메모리에 올라가있는 서블릿 객체는 더이상 사용 불가 
		//-> destroy() 호출 -> 브라우저에서 다시 호출하면 새로운 객체를 생성, init, service 한다. 
		System.out.println("destroy 호출");
	}
/*
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 초기 생성 후, 새로고침이나  새로 요청하는 경우는 service 메소드만 계속호출 된다. 
		//서블릿은 서버에 서블릿 객체를 여러개 만들지 않으므로, 
		// 요청이 여러번 들어오면, 실제 요청된 객체가 메모리에 있는지 없는지만 확인해서
		//있으면 service 만 요청 
		System.out.println("service 호출 ");
	}
*/

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		resp.setContentType("text/html");
		PrintWriter out = resp.getWriter();
		out.println("<html>");
		out.println("<head><title>form</title></head>");
		out.println("<body>");
		out.println("<form method='post' action='/exam31/LifecycleServlet'>");
		out.println("name : <input type='text' name='name' <br>");
		out.println("<input type='submit' value='ok'><br>");
		out.println("</form>");
		out.println("</body>");
		out.println("</html>");
		out.close();
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		resp.setContentType("text/html");
		PrintWriter out = resp.getWriter();
		String name = req.getParameter("name");
		//request는 요청정보를 추상화해서 갖고 있는 객체 
		//name인 파라미터 의 value 를 문자열 형태 name 에 대입 
		out.println("<h1>hello" + name + "</h1>");
		//받아온 응답결과를 넣어서, 출력 
		out.close();
	}

	
}

 

<html>
<head><title>form</title></head>
<body>
<form method='post' action='/exam31/LifecycleServlet'>
/* form 태그의 메소드 값과 action값 : submit이라는 버튼이 눌렸을때, action 주소로 요청
이때, 메소드는 post로 넣어달라고 요청 */
name : <input type='text' name='name' <br>
<input type='submit' value='ok'><br>
</form>
</body>
</html>

 doGet()  :   url 에서 넘어갔을 때는, GET 요청이 들어오므로, httpservlet 이 가진 service 메소드는 doGet()이라는 
 메소드를 호출-> doGet() 호출 , 

ㅇㅇㅇㅇ 을 요청해서,ok 하게 되면, submit 눌렸을때, doPost 메소드 실행 

: 똑같은 코드가 실행되지만, 프로그램이 동작되면서 응답결과가 매번 달라지는 동적인 페이지 

 

  • 해당 서블릿에 url 주소를 직접 입력하거나, 링크를 클릭하는 것 : GET방식으로 서버에 요청 

   --> 해당 서블릿의 service() 메소드는 자신의 doGet() 메소드를 호출 

 

  • 요청할 때, ok 값 제출시,  메소드가 post 방식으로 전달-> doPost를 호출해서, 안의 내용 출력

* Request , Response 객체 

( 웹 브라우저는 url을 통해서, 도메인과 포트번호를 이용해서 서버에 접속합니다. 그리고 path 정보, 클라이언트 ip,,요청 정보를 서버에게 전송 )

-> 클라이언트로부터 요청이 들어오면, WAS는 요청 시에 갖고있던 정보를 HttpServletRequest 객체를 생성해서 저장, 

HttpServletResponse 객체에 클라이언트에게 전송할 정보를 담아서, 생성된 두 객체들을 서블릿에게 전달합니다. 

-> 전달된 객체는 service(), doGet(), doPost() 같은 메소드의 파라미터로 전달되어서 사용

 

HttpServletRequest

  • http프로토콜의 request정보를 서블릿에게 전달하기 위한 목적으로 사용합니다.
  • 헤더정보, 파라미터, 쿠키, URI, URL 등의 정보를 읽어 들이는 메소드를 가지고 있습니다.
  • Body의 Stream을 읽어 들이는 메소드를 가지고 있습니다.

HttpServletResponse

  • WAS는 어떤 클라이언트가 요청을 보냈는지 알고 있고, 해당 클라이언트에게 응답을 보내기 위한 HttpServleResponse객체를 생성하여 서블릿에게 전달합니다.
  • 서블릿은 해당 객체를 이용하여 content type, 응답코드, 응답 메시지등을 전송합니다.

 - header 정보 읽어들이기

...더보기
package examples;

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

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 HeaderServlet
 */
@WebServlet("/header")
public class HeaderServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public HeaderServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.setContentType("text/html");
		PrintWriter out = response.getWriter();
		out.println("<html>");
		out.println("<head><title>form</title></head>");
		out.println("<body>");
		//요청이 들어올 때 모든 정보들은 WAS가 HttpServletRequest객체를 만들어서
		//객체 안에다가 정보들을 집어넣고, 해당 객체 request 를 파라미터로 받아서 사용 
		Enumeration<String> headerNames = request.getHeaderNames();
		//모든 헤더 이름을 문자열로 반환 
		while(headerNames.hasMoreElements()) {
			String headerName = headerNames.nextElement();
			String headerValue = request.getHeader(headerName);
			out.println(headerName+" ; "+headerValue+"<br>");
		}
		out.println("</body>");
		out.println("</html>");
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response); 
	}

}

- Parameter 정보 읽어들이기

...더보기
package examples;

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;

/**
 * Servlet implementation class ParameterServlet
 */
@WebServlet("/Param")
public class ParameterServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public ParameterServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.setContentType("text/html");
		PrintWriter out = response.getWriter();
		out.println("<html>");
		out.println("<head><title>form</title></head>");
		out.println("<body>");
		
		String name = request.getParameter("name");
		String age = request.getParameter("age");
		//request 한테 받은 정보로부터 파라미터 값을 전달 받아서, name, age 에 저장한다. 
		
		out.println("name: "+ name + "<br>");
		out.println("age: "+ age + "<br>");
	
		out.println("</body>");
		out.println("</html>");
	}

}

http://localhost:8080/exam31/Param?name=kim&age=5 

 ?이후에 계속 이어질 수 있고, 여러 값을 주기 위해서 &로 연결