Servlet의 개념과 동작 과정을 이해한다.
Goal
Web Service의 기본적인 동작 과정을 이해한다.
사용자 입력을 위한 HTML Form을 이해한다.
Servlet을 이해한다.
Web Service의 기본적인 동작 과정
HTML Form -> Servlet -> HTML Page
1. 사용자가 웹 페이지 form(HTML Form)을 통해 자신의 정보를 입력한다. (Input)
2. Servlet의 doGet() 또는 doPost() 메서드는 입력한 form data에 맞게 DB 또는 다른 소스에서 관련된 정보를 검색한다.
3. 이 정보를 이용하여 사용자의 요청에 맞는 적절한 동적 컨텐츠(HTML Page)를 만들어서 제공한다. (Output)
HTML Form
input elements(Ex. 텍스트 상자)가 포함된 웹 페이지의 한 부분(section)
사용자가 입력한 정보(form contents)를 웹 서버로 전송하기 위한 submit element(Ex. 버튼)가 존재한다.
action에는 form을 처리하는 서버 쪽 URL을 명시한다.
클라이언트(browser)가 요청하는 URL 정보
요청을 보낼 서버의 IP 주소 : Port 번호 / App 이름 / 달라고 요청하는 HTML
Ex) localhost:8080/FormHandlingServlet/LoginForm.html
IP 주소
요청을 보낼 서버의 “위치”를 의미한다.
browser와 WAS(Tomcat)가 같은 PC에 있으면 “IP 주소 = localhost”
Port 번호
해당 위치 안의 “특정 사람”을 의미한다.
HTML 이름
HTML 이름에 해당하는 HTML 문서를 받아온다.
browser는 받아온 HTML 문서 안의 html 태그들(Ex. h2, br 등)을 parsing(기계어로 번역)한다.
마지막으로 이 내용을 browser에서 rendering(그리기)한다.
LoginForm.html 내용 (간단한 예시)
<form name="loginForm" method="post" action="loginServlet">
Username: <input type="text" name="username"/> <br/>
Password: <input type="password" name="password"/> <br/>
<input type="submit" value="Login" />
</form>
method=”post”
원하는 동작에 따라 HTTP 메서드를 사용한다.
method=”get”
action=”loginServlet”
URL of the servlet
해당 URL로 request가 간다. 즉, WAS에서의 어떤 Servlet인지 지정하는 것
type=”submit”
버튼을 누르면 사용자가 입력한 인자들이 Servlet으로 넘어간다.
Form Tag 속성
Form Tag 속성을 이용하여 어디로, 어떤 방식으로 전송할지 정한다.
action : form을 전송할 서버 쪽 스크립트 파일 지정
name : form을 식별하기 위한 이름 지정
accept-charset : form 전송에 사용할 문자 인코딩을 지정
target : action에서 지정한 스크립트 파일을 현재 창이 아닌 다른 위치에서 열리도록 지정
method : form을 서버에 전송하는 방식으로, HTTP 메서드 지정 (GET 또는 POST)
아래 추가 설명
enctype : 넘기는 Content의 Type 지정 (주로 파일을 넘길 때 사용)
type은 multipart/form-data 로 지정해서 사용
Form Methods
form을 서버에 전송하는 방식으로, 두 가지 HTTP 메소드 지정할 수 있다.
GET Method
사용자가 입력한 내용(form data)이 URL 뒤에 텍스트 문자열로 추가된다.
크기 제한: 1024 characters
data는 ?를 기준으로 action URL과 분리된다.
Ex. http://www.test.com/hello?key1=value1&key2=value2
브라우저에서 웹 서버로 정보를 전달하는 기본 메서드(Default Method)
HTTP 메서드를 지정하지 않으면 GET Method를 호출한다.
서버에 전달하는 data에 암호와 같은 민감한 정보가 있는 경우는 GET Method를 사용하지 않는다.
URL은 모두에게 노출되는 정보이기 때문에 보안상 적절하지 않다.
GET 메서드의 사용
Query-Type actions: DB에 영향을 주지 않는 단순히 읽기 위주(read operation)의 작업
Idempotemt actions: 몇 번이고 같은 연산을 반복해도 같은 값이 나오는 작업
POST Method
사용자가 입력한 내용(form data)을 별도의 메시지로 보낸다.
Request Body에 data를 추가한다.
URL에 직접적으로 data가 노출되지 않기 때문에 GET Method보다 보안상으로 조금 더 안전하다.
POST 메서드의 사용
actions with side-effects: DB에 영향을 주는 작업
2. Servlet이란
Servlet의 개념
웹 기반의 요청에 대한 동적인 처리가 가능한 하나의 클래스이다.
Server Side에서 돌아가는 Java Program
개발자가 작성해야 하는 부분
Servlet Program의 기본적인 동작 과정
Web Server는 HTTP request를 Web Container(Servlet Container)에게 위임한다.
1) web.xml 설정에서 어떤 URL과 매핑되어 있는지 확인
2) 클라이언트(browser)의 요청 URL을 보고 적절한 Servlet을 실행
https://gmlwjd9405.github.io/2018/10/29/web-application-structure.html 참고
Web Container는 service() 메서드를 호출하기 전에 Servlet 객체를 메모리에 올린다.
1) Web Container는 적절한 Servlet 파일을 컴파일(.class 파일 생성)한다.
2) .class 파일을 메모리에 올려 Servlet 객체를 만든다.
3) 메모리에 로드될 때 Servlet 객체를 초기화하는 init() 메서드가 실행된다.
Web Container는 Request가 올 때마다 thread를 생성하여 처리한다.
각 thread는 Servlet의 단일 객체에 대한 service() 메서드를 실행한다.
참고 Servlet Program에서 Thread의 역할
Thread란? 운영체제로부터 시스템 자원을 할당받는 작업의 단위
https://gmlwjd9405.github.io/2018/09/14/process-vs-thread.html 참고
Servlet Program에서 thread가 수행할 메서드가 지정/할당되면
thread는 생성 후 즉시 해당 메서드만 열심히 수행한다.
해당 메서드가 return하면 thread는 종료되고 제거된다.
즉, 실제로 thread의 역할: Servlet의 doGet() 또는 doPost()를 호출하는 것이다.
Web Container(Servlet Container)는 thread의 생성과 제거를 담당한다.
하지만 thread의 생성과 제거의 반복은 큰 오버헤드를 만든다.
이를 위해 Tomcat(WAS)은 “Thread Pool”(미리 thread를 만들어 놓음) 이라는 적절한 메커니즘을 사용하여 오버헤드를 줄인다.
즉, WAS는 Servlet의 life cycle을 담당한다.
웹 브라우저 클라이언트의 요청이 들어왔을 때 Servlet 객체 생성은 WAS가 알아서 처리한다.
WAS 위에서 Servlet이 돌아다니고 개발자는 이 Servlet을 만들어야 한다.
Servlet Life Cycle
클라이언트의 요청이 들어오면 WAS는 해당 요청에 맞는 Servlet이 메모리에 있는지 확인한다.
만약 메모리에 없다면 해당 Servlet Class를 메모리에 올린 후(Servlet 객체 생성) init 메서드 실행
이후 service 메서드를 실행
메모리에 있다면 바로 service 메서드 실행
if (메모리에 없음) {
// 해당 서블릿 클래스를 메모리에 올림
// init() 메소드를 실행
}
// service()메소드를 실행
init()
한 번만 수행된다.
클라이언트(browser)의 요청에 따라 적절한 Servlet이 생성되고 이 Servlet이 메모리에 로드될 때 init() 메서드가 호출된다.
역할: Servlet 객체를 초기화
service(request, response)
응답에 대한 모든 내용은 service() 메서드에 구현해야 한다.
Servlet이 수신한 모든 request에 대해 service() 메서드가 호출된다.
HttpServlet을 상속받은 Servlet 클래스(이하 하위 클래스)에서 service() 메서드를 오버라이드하지 않았다면, 그 부모인 HttpServlet의 service()가 호출된다.
HttpServlet의 service() 메서드는 템플릿 메서드 패턴으로 구현되어 있다.
service() 메서드는 request의 type(HTTP Method: GET, POST, PUT, DELETE 등)에 따라 적절한 메서드(doGet, doPost, doPut, doDelete 등)를 호출한다.
즉, 하위 클래스에서 doGet, doPost 등의 메서드를 오버라이드해두면 HttpServlet의 service() 메서드가 요청에 맞는 메서드(하위 클래스에서 오버라이드한 메서드)를 알아서 호출할 수 있게 되는 것이다.
메서드가 return하면 해당 thread는 제거된다.
destroy()
한 번만 수행된다.
Web Application이 갱신되거나 WAS가 종료될 때 호출된다.
역할: Servlet 객체를 메모리에서 제거
Servlet의 메서드 구현 (간단한 예시)
// `javax.servlet.http.HttpServlet`를 상속받은 Servlet 클래스
public class LoginServlet extends HttpServlet {
// doPost()를 재정의
protected void doPost(HttpServletRequest request, HttpServletResponse response throws ServletException, IOException {
// read form fields
String username = request.getParameter("username");
String password = request.getParameter("password");
// get response writer
PrintWriter writer = response.getWriter();
/* 여기서 -> DB 접근 등 Business Logic 부분을 처리 */
// build HTML code (view 생성 부분)
String htmlResponse = "<html>";
htmlResponse += "<h2>Your username is: " + username + "<br/>";
htmlResponse += "Your password is: " + password + "</h2>";
htmlResponse += "</html>";
// return response
writer.println(htmlResponse);
}
}
// javax.servlet.http.HttpServlet
를 상속받은 Servlet 클래스
public class LoginServlet extends HttpServlet {
// doPost()를 재정의
protected void doPost(HttpServletRequest request, HttpServletResponse response throws ServletException, IOException {
// read form fields
String username = request.getParameter("username");
String password = request.getParameter("password");
// get response writer
PrintWriter writer = response.getWriter();
/* 여기서 -> DB 접근 등 Business Logic 부분을 처리 */
// build HTML code (view 생성 부분)
String htmlResponse = "<html>";
htmlResponse += "<h2>Your username is: " + username + "<br/>";
htmlResponse += "Your password is: " + password + "</h2>";
htmlResponse += "</html>";
// return response
writer.println(htmlResponse);
}
}
WAS는 웹 브라우저로부터 요청을 받으면
요청할 때 가지고 있는 정보를 HttpServletRequest객체를 생성하여 저장한다.
웹 브라우저에게 응답을 보낼 때 사용하기 위하여 HttpServletResponse객체를 생성한다.
생성된 HttpServletRequest, HttpServletResponse 객체를 Servlet에게 전달한다.
개발자는 일반적으로 javax.servlet.http.HttpServlet를 상속받은 Servlet 클래스를 작성한다.
HttpServletRequest request 파라미터를 통해 사용자가 입력한 form data를 읽는다.
HttpServletResponse response 파라미터를 통해 출력/결과 Web Page를 생성한다.
개발자는 Servlet 클래스에 doGet() 또는 doPost() 중 적어도 하나를 재정의하여 작성한다.
protected doGet()(HttpServletRequest request, HttpServletResponse response){}
protected doPost()(HttpServletRequest request, HttpServletResponse response){}
HttpServletRequest request 객체
사용자가 HTML Form에 입력한 내용(username과 password)을 request 객체에서 받아온다.
즉, HTTP 프로토콜의 Request 정보를 Servlet에게 전달
헤더 정보, 파라미터, 쿠키, URI, URL, Body의 Stream 등을 읽어 들이는 메서드가 있다.
getHeader(“원하는 헤더 이름”)
이 메서드를 통해 원하는 헤더 정보를 확인할 수 있다.
getParameter()
이 메서드를 호출하여 form parameter 값을 가져온다.
이런 parameter 값은 URL 또는 form의 input tag를 통해서 넘어올 수 있다.
Ex.
String name = request.getParameter("firstname");
int year = Integer.parseInt (request.getParameter("year"));
getParameterValues()
form parameter가 두 번 이상 나타나고 여러 개의 값을 반환할 때 이 메서드를 호출한다. (Ex. checkbox)
Ex.
String languages[] = request.getParameterValues("language");
HttpServletResponse response 객체
인자의 내용에 맞게 동적인 HTML 코드를 생성하여 response 객체에 담아 반환한다.
getWriter() 메서드를 호출하여 PrintWriter 객체을 가져온 후 해당 객체에서 print, println 메서드를 실행한다.
즉, form data를 처리한 결과를 Web Page에 생성(view 생성)하여 반환한다.
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<h2> Welcome </h2>");
'HTML' 카테고리의 다른 글
Servlet 실습 2 (html client에서 받은 데이터를 servlet 서버로 데이터를 날려준다. ) (0) | 2021.03.10 |
---|---|
Servlet 실습 1 (0) | 2021.03.10 |
Web server (0) | 2021.03.10 |
JSON <자신이 읽은 책 5권을 JSON파일로 제작후 테이블로 시각화 하기> (0) | 2021.03.09 |
XML / <자신이 읽은 책 5권을 XML파일로 제작후 테이블로 시각화 하기> (0) | 2021.03.09 |