🔷 프로그램
: 명령어의 모음집
요청(Request)
에 응답(Response)
하는 식으로 프로그램 전송이 http
라는 약속 및 규제 아래에 이루어졌다.💡 요청을 주는 쪽:
Client
💡 응답하는 쪽:Server
💡 브라우저로 자료를 넘기는 서버 영역에서 활동하는 사람을 백엔드 개발자, 클라이언트가 보게 되는 브라우저의 모양을 잡고 서버와 통신하여 데이터를 받아 처리하는 사람을 프론트엔드 개발자라고 한다.
🔷 URL(Uniform Resource Locator)
🔷 웹 페이지(Web page)
🔷 웹 서버(Web Server)
🔷 웹 어플리케이션(Web Application)
🔷 웹 어플리케이션 서버(Web Application Server, WAS
)
🔷 Apache Tomcat
대표적인 오픈소스 WAS
필자는 9 버전을 다운받았다.
이클립스에서 Tomcat에 서버 등록하기
처음 접속 시에는 서버가 없다.
파란 링크를 눌러주면 새로운 서버를 만들 수 있는데 여기서 Apache Tomcat 9
버전 선택
이전에 다운 받은 톰캣이 들어있는 파일을 설치 경로로 잡고 마무리한다.
서버가 새로 열린 것이 확인되었다.
🔷 구조
💡 웹 어플리케이션 설정파일인
web.xml
도WebContent/WEB-INF/
에 위치한다.
💡 생성 팝업
🖥 HelloServlet
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 HelloServelt
*/
@WebServlet("/HelloServelt")
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public HelloServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter writer = response.getWriter();
writer.append("<html>");
writer.append("<head>");
writer.append("<title>Hello</title>");
writer.append("</head>");
writer.append("<body>");
writer.append("<h1>Hello Servlet!</h1>");
writer.append("</body>");
writer.append("</html>");
}
}
서버 Run 시 작동하는 화면이다.
실행시 열리는 서버 http://localhost:8080/~/# 에서 ~ 부분에 context root가 들어간다. #부분에는 요청이 들어오는데 이 요청이름이 겹치는 것을 감안하여 넣은 것이 context root이다.
🔷 Server + Applet
1. web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
<display-name>BackEnd_Day01_Servlet</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>myservlet.MyServlet4</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/MyServlet</url-pattern>
</servlet-mapping>
</web-app>
2. Annotation
@WebServlet("/MyServlet2")
public class MyServlet5 extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter writer = response.getWriter();
writer.append("<html>");
writer.append("<head>");
writer.append("<title>Hello</title>");
writer.append("</head>");
writer.append("<body>");
writer.append("<h1>Hello Servlet5</h1>");
writer.append("</body>");
writer.append("</html>");
}
}
1. Interface Servlet
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
//해당 클래스를 서블릿으로 만들기 위해서는 Servlet을 구현해야한다.
public class MyServlet1 implements Servlet {
@Override
public void destroy() {
//서블릿이 소멸될때 동작
}
@Override
public ServletConfig getServletConfig() {
//서블릿 설정을 반환
return null;
}
@Override
public String getServletInfo() {
//서블릿의 정보를 문자열로 반환
return null;
}
@Override
public void init(ServletConfig config) throws ServletException {
//서블릿을 초기화
}
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
//요청과 응답 같은것을 처리
}
}
2. class GenericServlet
import java.io.IOException;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
// 제네릭 서블릿은 추상 클래스이다
public class MyServlet2 extends GenericServlet {
private static final long serialVersionUID = 1L;
@Override
public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
//서비스만 구현하면 된다
}
}
3. class HttpServlet
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//고정 방식으로 등록
public class MyServlet4 extends HttpServlet {
private static final long serialVersionUID = 1L;
// do~ () 메서드 하나 이상은 구현해야한다.
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter writer = response.getWriter();
writer.append("<html>");
writer.append("<head>");
writer.append("<title>Hello</title>");
writer.append("</head>");
writer.append("<body>");
writer.append("<h1>Hello Servlet4</h1>");
writer.append("</body>");
writer.append("</html>");
}
}
서블릿 인스턴스는 서블릿이 포함된 웹 컨테이너에 의해 제어된다.
서블릿 인스턴스가 존재하지 않으면 다음과 같은 작업을 수행한다.
1) 서블릿 클래스 로드 - JVM에 로드
2) 서블릿 클래스 인스턴스 생성 - JVM의 Tomcat이 생성해준다.
3) 서블릿 인스턴스 초기화
4) 웹 컨테이너에 의한 서비스 메서드 호출
5) destroy 메서드를 호출하여 서블릿 종료
서비스 메서드는 요청이 들어올 때 마다 호출된다.
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 LifeCycle
*/
@WebServlet("/LifeCycle")
public class LifeCycle extends HttpServlet {
private static final long serialVersionUID = 1L;
int initCount = 1;
int doGetCount = 1;
int destroyCount = 1;
/**
* @see HttpServlet#HttpServlet()
*/
public LifeCycle() {
System.out.println("생성자 호출");
}
/**
* @see Servlet#init(ServletConfig)
*/
public void init(ServletConfig config) throws ServletException {
System.out.println("init 메서드 호출"+ (initCount++));
}
/**
* @see Servlet#destroy()
*/
public void destroy() {
System.out.println("destroy 메서드 호출 " + (destroyCount++));
System.out.println("끝");
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doGet 메서드 호출" + (doGetCount++));
}
}
1. 처음 실행 시
2. 새로고침 시
3. 종료 시 (여기선 수정 후 저장)
4. 링크에 커서를 대고 다시 한번 엔터를 누르면?
다시 생성. 이런 식으로 라이프 사이클이 돌아간다.
🔷 GET과 POST
GET | POST |
---|---|
지정된 리소스에서 데이터를 요청하는 데 사용 | 리소스를 생성/업데이트 하기 위해 서버에 데이터를 보내는데 사용 |
query string(name/value 쌍)이 URL에 포함되어 전송됨. POST와 비교하여 보안에 취약함. | HTTP header의 body에 파라미터를 포함하여 전송, 데이터 길이에 대한 제한 없음, 매개변수가 브라우저나 웹 서버에 저장되지 않음. |
URL이 길이 제한이 있으므로, 전송가능한 데이터의 길이가 제한적, ASCII문자만 가능 | 제한 없음, 바이너리 데이터도 허용 |
💡 READ 작업은 GET, 그 외의 작업은 POST 추천
이전에 JS 시리즈 포스팅에서 언급한 적이 있다.
🔷 URL 구성요소
https://www.google.com/search?q=gue
/ 프로토콜 / 서버 / (context root) / 경로 ? 쿼리 스트링
구성요소 | 설명 |
---|---|
프로토콜 | 절차를 포함한 통신규약 |
서버 | 웹 페이지를 요청할 서버의 주소, 실제 IP주소나 도메인을 입력할 수 있다. |
경로 | 서버 내의 상세 경로 |
쿼리 스트링 | 추가로 서버로 데이터를 전송하기 위해서 사용한다. '?' 마크로 시작 표시, 파라미터가 여러 개일 경우 '&'로 구분 |
🔷 Front-Controller