728x90
Servlet Life Cycle
- 서블릿 클래스는 javaSE에서의 class와는 다르게 main method가 없다. 즉 객체의 생성부터 사용(method call)의 주체가 사용자가 아닌 Servlet Container(Servlet Engine이라 함. 얘를 WAS라 함 우리는 WAS 중에 톰캣이라는 애를 씀)에게 있다.
- 클라이언트가 요청을 하게되면 Servlet Container는 Servlet 객체를 생성(한번만)하고, 초기화(한번만)하며 요청에 대한 처리(요청시마다 반복)를 하게 된다. 또한 Servlet객체가 필요없게 되면 제거하는 일까지 Contatiner가 담당하게 된다. (WAS가 쓰레드를 처리해줘서 가능). 웹페이지에 드가는 사람이 한명일 수는 없자너
서블릿의 생명주기 메서드
- init()은 시작할(최초의 한번만) 때 한번, destroy()는 마지막에 한번 호출
- 서블릿 하나만 만들어지고 한번만 초기화(init())됨 ! 클라이언트가 만명이든 몇명이든 .
- 클라이언트가 호출할 때마다(서비스실행) 쓰레드가 만들어지면서 멀티스레드가 돈다!
- init()이 계속 실행되는게 아님
- 리로드하면 다시 로드하기 전에 destroy() 호출!
- 404에러 → 오타!
- 여기서 컨텍스트 루트를 바꿀 수 있음
- 이렇게 두개(1번, 2번) 다 바꿔줘야 컨텍스트 루트 바뀐 거로 실행됨
URL
- URI(Uniform Resource Identifier) 가 상위 개념이고 URI 밑에 URL(Uniform Resource Locator)과 URN(Uniform Resource Name)이 있음
- URL은 유일성을 보장하고 URN은 유일성 확보에 실패해서 로컬로만 사용함
DB 연결 (방문자 몇명인지 예제)
Servlet 코드
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/counter")
public class CounterServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
public void init() throws ServletException {
try {
// 2-1. Driver Loading
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
// 당신은 XXXXXXXX번째 방문자입니다.
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int cnt = 0;
int totalLen = 8;
int zeroLen = 0;
// 1. data get
// 2. logic
// 2-2. DB Connection (conn 생성)
// 2-3. SQL 실행 준비
// SQL문
// pstmt 생성 (치환변수 값 세팅)
// 2-4. SQL 실행
// a. DML (I U D) : int cnt = pstmt.executeUpdate();
// b. Query (S) : ResultSet rs = pstmt.executeQuery();
// rs.next() [단독, if, while]
// rs.getXXX("col_name");
// 2-5. DB close (역순)
// DB Logic
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/ssafyweb?serverTimezone=UTC&useUniCode=yes&characterEncoding=UTF-8", "ssafy", "ssafy");
String sql = "select cnt from counter";
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
rs.next();
cnt = rs.getInt(1);
pstmt.close();
sql = "update counter set cnt = cnt + 1";
pstmt = conn.prepareStatement(sql);
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if(rs != null)
rs.close();
if(pstmt != null)
pstmt.close();
if(conn != null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
// Business Logic
String cntStr = cnt + ""; //"138"
int cntLen = cntStr.length(); // 3
zeroLen = totalLen - cntLen;
// 3. response page
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println(" <body>");
out.println(" <div align=\\"center\\">");
// out.print("당신은 ");
for(int i=0;i<zeroLen;i++)
out.print("<img src=\\"/bw/img/img_0.png\\" width=\\"80\\">");
for(int i=0;i<cntLen;i++)
out.print("<img src=\\"/bw/img/img_" + cntStr.charAt(i) + ".png\\" width=\\"80\\">");
// out.println("번째 방문자입니다.");
out.println(" </div>");
out.println(" </body>");
out.println("</html>");
}
}
- 드라이버 로딩은 한번만 하면됨 최초에! → init()에 넣어주면 되지 않을까?
JSP 코드
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.sql.*"%>
<%!
@Override
public void init() throws ServletException {
try {
// 2-1. Driver Loading
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
%>
<%
int cnt = 0;
int totalLen = 8;
int zeroLen = 0;
//1. data get
//2. logic
// 2-2. DB Connection (conn 생성)
// 2-3. SQL 실행 준비
// SQL문
// pstmt 생성 (치환변수 값 세팅)
// 2-4. SQL 실행
// a. DML (I U D) : int cnt = pstmt.executeUpdate();
// b. Query (S) : ResultSet rs = pstmt.executeQuery();
// rs.next() [단독, if, while]
// rs.getXXX("col_name");
// 2-5. DB close (역순)
//DB Logic
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/ssafyweb?serverTimezone=UTC&useUniCode=yes&characterEncoding=UTF-8", "ssafy", "ssafy");
String sql = "select cnt from counter";
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
rs.next();
cnt = rs.getInt(1);
pstmt.close();
sql = "update counter set cnt = cnt + 1";
pstmt = conn.prepareStatement(sql);
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if(rs != null)
rs.close();
if(pstmt != null)
pstmt.close();
if(conn != null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
//Business Logic
String cntStr = cnt + ""; //"138"
int cntLen = cntStr.length(); // 3
zeroLen = totalLen - cntLen;
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<div align="center">
<h2>JSP로 만든 카운터</h2>
<%
for(int i=0;i<zeroLen;i++) {
%>
<img src="/bw/img/img_0.png" width="80">
<%
}
for(int i=0;i<cntLen;i++) {
%>
<img src="/bw/img/img_<%= cntStr.charAt(i) %>.png" width="80">
<%
}
%>
</div>
</body>
</html>
결과
JSP는 다음 글에!
728x90