[Web] Servlet

soyeon·2022년 7월 25일
0
post-thumbnail

🛫Web🌏
: Internet 상에서 HTTP를 사용하는 World Wide Web service

Request & Response

Request

: Web client가 Request를 보낸다.

Request URL : https//localhost:8080/path/file => (protocol/ip:port/resource/Query String)

Query String
: 무조건 '?'로 시작한다. key=value 쌍으로 구성되어 있다. 여러개가 있을 때는 '&'로 연결한다.
ex) ?key=value&key=value&key=value

🙃 Web server 측면에서는 HTTP Request를 세가지 형태로 나누어서 받는다. 🙃

  1. Request line
    : HTTP method, URL(resource 경로), HTTP version
    ex) GET URL HTTP/1.1

  2. Request header
    : 여러 부가적인 정보들이 전달된다.
    - client의 IP
    - client가 사용하는 언어(Accept-language)
    - content-type
    ...

  3. Request body
    : Query String의 정보가 전달된다.

=> 서로 줄바꿈으로 구분된다.

HTTP method
: client가 server에 request를 보내는 방식

Request method

- GET
: Query String을 이용한다.
1. browser 입력창에 URL을 입력하고 enter를 치는 경우
2. hypertext(링크)를 이용해서 request를 보내는 경우
3. Form tag를 이용하는데 method가 "GET"인 경우

💡 장점 - 간단하다.
💣 단점 - 보내려는 데이터가 URL에 보인다(보안X). 대량의 데이터 전송이 안된다.

- POST
: Query String을 쓰지 않고, Request header에 데이터를 포함 시킨다.
1. Form tag를 이용하는데 method가 "POST"인 경우

💡 장점 - URL에 데이터가 노출되지 않는다(보안성이 있다라고 하기는 힘들다. GET 방식보다는 낫다). 길이 제한이 없다.

Response

: browser가 받는 정보이다.

  1. Response line
    : Protocol, status code(상태 코드), 설명
    ex) HTTP/1.1 200 OK

  2. Response header
    : web client에게 알려주는 결과 데이터에 대한 정보이다.
    - encoding
    - content-type : MIME(HTML, Image, VIdeo, ...)
    - size
    - server 설명(apache, tomcat, ...)
    ...

  3. Response body
    : 요청한 HTML 파일이 전달된다.

Web project 시작 전에 환경 구축하기 🌱

기본적인 Web project 만들기

static web

😮 간단한 static web application 구현

dynamic web

😮 간단한 dynamic web application 구현

HTTP client-server 구조 (Static Web)

: 상대적으로 다수의 Client가 소수의 Server에 접속해서 서비스를 제공 받는 형태이다.
HTTP client-server 구조

-> 우리는 resource를 구현한다.

Dynamic Web (Servlet)

: Dynamic web은 프로그램을 실행하고, 그 결과를 response로 돌려준다.
하지만 web server는 외부 프로그램을 실행시킬 능력이 없기 때문에 web applicaion server(WAS)를 이용한다.
이 안에 프로그램을 만들어 놓고, 클라이언트가 요청하는 프로그램을 찾고 실행시켜서 결과를 web server에게 돌려주고, web server가 client에게 response를 돌려준다.

Apache Tomcat
: HTTP Server + Servlet Container

Java Servlet을 만들기 위해서는 Java에서 제공하는 HTTPServlet을 상속해서 구현한다. overriding 해서 사용한다.

Servlet 실행 Mechanism

Servlet Mechanism
1. 처음 request가 들어왔을 때, Web Server는 Servlet container에게 request를 넘긴다.

  1. Servlet container는 request와 response 객체를 만든다.

  2. request에서 요청하는 Servlet 객체를 찾는다.
    처음 실행이라서 없는 경우, class에서 servlet instance를 만들어낸다.
    만들어진 instance 안에는 service(), doGet(), doPost() method들이 존재한다.

  3. Servlet이 가진 method를 호출하는 thread를 만든다.
    client에게 요청이 들어올 때마다 thread가 만들어지면서 method를 호출한다.
    thread가 request, response 객체를 method(service)를 호출하면서 인자로 넣어준다.

service()
client 요청의 method를 파악한 후에 그에 맞는 method를 호출한다.
=> doGet(), doPost()

  1. doGet()이나 doPost()가 실행되고, 그에 대한 결과가 response로 전달된다.

  2. 실행이 끝나고, 필요 없는 객체인 thread, request, response는 사라진다. 만들어진 servlet 객체는 사라지지 않는다.

Servlet의 문제점

  1. Layered Architecture의 적용이 필요하다.
    => MVC pattern
  2. Servlet의 데이터 공유??
  3. 출력 문제 -> Java code 내에서 HTML을 포함시켜야 한다.
    => JSP나 Front-end 자체 처리로 해결할 수 있다.
  4. HTTP protocol은 Stateless protocol
    : "Session 처리"를 통해서 이 문제를 해결한다.
    session 처리
  • 연습 코드
package lecture0725;

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;
import javax.servlet.http.HttpSession;

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

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 1. 입력
		String id = request.getParameter("myID");
		// 2. 로직
		//	  해당 client에게 session을 할당하거나 할당된 session을 찾아와요
		HttpSession session = request.getSession();
		session.setAttribute("id", id);
		// 3. 출력
	}

	/**
	 * @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);
	}

}

package lecture0725;

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;
import javax.servlet.http.HttpSession;

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

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 1. 입력
		// 2. 로직
		HttpSession session = request.getSession();
		String result = (String)session.getAttribute("id");
		// 3. 출력
		response.setContentType("text/html; charset=UTF-8");
		PrintWriter out = new PrintWriter(response.getOutputStream());		
		out.println("얻어낸 결과는 : " + result);
		out.close();
	}

	/**
	 * @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);
	}

}

<실행 결과>
http://localhost:8080/html/mysession?myID=kim
http://localhost:8080/html/usesession
=> 얻어낸 결과는 : kim

Servlet Context

: 모든 Servlet이 공유하는 객체

우리 context root 안에 Servlet Context 객체는 1개이다.

  • 예제 코드
package lecture0725;

import java.io.IOException;

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

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 1. 입력
		// 2. 로직
		//	  ServletContext를 사용해 보아요
		//	  ServletContext 객체를 얻어와요.
		ServletContext context = getServletContext();
		// 	  획득한 Servlet Context에 특정 정보를 저장해 보아요
		context.setAttribute("product", "냉장고");
		// 3. 출력
	}

	/**
	 * @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);
	}
}

package lecture0725;

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

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

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 1. 입력
		// 2. 로직
		ServletContext context = getServletContext();
		String product = (String)context.getAttribute("product");
		// 3. 출력
		response.setContentType("text/html; charset=UTF-8");
		PrintWriter out = new PrintWriter(response.getOutputStream());
		out.println("얻어온 결과는 : " + product);
		out.close();
	}

	/**
	 * @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);
	}

}

<실행 결과>
1. http://localhost:8080/html/servletb
=> 얻어온 결과는 : null
2. http://localhost:8080/html/servleta
3. http://localhost:8080/html/servletb
=> 얻어온 결과는 : 냉장고

0개의 댓글