๐ ๏ธBackend/๐ณSpring
[Spring Framework] Servlet API, HttpServlet, DispatcherServlet, Tomcat ์์๋ณด๊ธฐ
junbin2
2025. 6. 28. 00:46
โ 1. Servlet API ๋?
package jakarta.servlet;
import java.io.IOException;
public interface Servlet {
void init(ServletConfig var1) throws ServletException; // Servlet ์์ฑ
ServletConfig getServletConfig();
// ์์ฒญ์ ๋ฐ์ ์ฒ๋ฆฌํ๋ ํต์ฌ ๋ฉ์๋
void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
String getServletInfo();
void destroy(); // Servlet ์ญ์
}
- ์๋ธ๋ฆฟ์ ์๋ฐ ๊ธฐ๋ฐ ์๋ฒ ์ฌ์ด๋ ์ปดํฌ๋ํธ ๊ธฐ์ ์ด๋ค. ์ฆ, ์น์ ๊ตญํ๋์ง ์๊ณ ๋ค์ํ ์์ฒญ-์๋ต ๋ชจ๋ธ์ ์ฒ๋ฆฌํ ์ ์๋ ๋ฒ์ฉ ์ธํฐํ์ด์ค๋ก ๋ง๋ค์ด์ก๋ค. ํ์ง๋ง ์ง๊ธ์ ๊ฑฐ์ 100%์ ๊ฐ๊น๊ฒ HTTP ์์ฒญ์ ์ฒ๋ฆฌํ๋ ๋ฐ ์ฌ์ฉ๋๊ธฐ ๋๋ฌธ์ ์น ๊ธฐ์ ์ฒ๋ผ ์ฌ๊ฒจ์ง.
- ๊ทธ๋์ ์ค์ ๋ก๋ ์๋ธ๋ฆฟ์ด๋ผ๊ณ ํ๋ฉด HttpServlet ๊ธฐ๋ฐ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ปํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์.
- ํ์ง๋ง, HttpServlet ์ ๊ฒฐ๊ตญ Servlet API ํ์์ ๋ง๊ฒ ๊ตฌํ ๋ ํด๋์ค์ด๋ค.
- Servlet ์ ์๋ฐ ํ๋ซํผ ์ ์ฉ ๊ธฐ์ ์ด๋ค. ์ฆ, ์๋ฐ์์๋ง ์ฌ์ฉ์ ํ๋ ๊ฐ๋ ์ด Servlet์ด๋ฉฐ, ์๋ฐ์์ ๋ง๋ ๊ฐ๋ ์ด๋ค.
- ํด๋น Servlet ์ API ์ฆ, ์ธํฐํ์ด์ค์ ์ถ์๋ฉ์๋๋ก ๋ง๋ค์ด์ ธ ์์ผ๋ฉฐ, API ํ์์ ๋ง๊ฒ ๊ตฌํ์ ํด์ผ ํ๋ค.
- ์ ๋ฆฌํ๋ฉด, Servlet API ์์ฒด๋ ์๋ธ๋ฆฟ์ ๊ธฐ๋ณธ ๋์ ์์น์ ์ ์ํ ์ต์์ ์ธํฐํ์ด์ค์ด๋ค.
(1) Servlet ์ด์
- ์๋ฒ(Server) + ์ฑ๋ฆฟ(Applet) ์ ํฉ์ฑ์ด์ด๋ค.
[ Applet ์ด๋? ]
- ์๋ฐ ์ด์ฐฝ๊ธฐ์ ์ฌ์ฉ๋๋ ์ฉ์ด๋ก, ์น ๋ธ๋ผ์ฐ์ ์์ ์คํ๋๋ ์์ ์๋ฐ ํ๋ก๊ทธ๋จ์ ์๋ฏธํ๋ค.
- Application + let ์ ํฉ์ฑ์ด ์ด๋ค.
- Application: ์ผ๋ฐ์ ์ธ ํ๋ก๊ทธ๋จ, ํนํ ๋ฐ์คํฌํ์ด๋ ์๋ฒ ๋ฑ์์ ์คํ๋๋ ์ ์ฒด์ ์ธ ์ํํธ์จ์ด๋ฅผ ์๋ฏธํจ.
- let: ์์ด์์ "์์ ๊ฒ"์ ์๋ฏธํ๋ ์ ๋ฏธ์ฌ์ด๋ค.
- ์ ๋ฆฌํ๋ฉด ์์ ์ ํ๋ฆฌ์ผ์ด์ ์ฆ, ๊ฒฝ๋ํ ๋๊ณ ์ ํ๋ ๊ธฐ๋ฅ์ ์ํํ๋ ํ๋ก๊ทธ๋จ์ ์๋ฏธํ๋ค.
โ 2. Servlet API ๊ตฌ์กฐ
package jakarta.servlet;
import java.io.IOException;
public interface Servlet {
void init(ServletConfig var1) throws ServletException; // Servlet ์์ฑ
ServletConfig getServletConfig();
// ์์ฒญ์ ๋ฐ์ ์ฒ๋ฆฌํ๋ ํต์ฌ ๋ฉ์๋
void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
String getServletInfo();
void destroy(); // Servlet ์ญ์
}
(1) init(ServletConfig var1)
- ์ด๊ธฐํ ๋ฉ์๋๋ก, ์๋ธ๋ฆฟ์ด ์์ฑ๋ ํ ์ต์ด๋ก ํ ๋ฒ๋ง ํธ์ถ์ด ๋๋ค.
- ์ฆ, ํ ๋ฒ๋ง ํธ์ถ์ด ๋์ด์ ์๋ธ๋ฆฟ์ด ์์ฑ์ด ๋๊ณ ์ฌ์ฉ์ด ์ข ๋ฃ๊ฐ ๋๋ฉด ์ ๊ฑฐ ๋ฉ์๋๊ฐ ํธ์ถ์ด ๋๋ค.
- ServletConfig ๊ฐ์ฒด๋ฅผ ํตํด ์๋ธ๋ฆฟ ์ด๊ธฐํ ํ๋ผ๋ฏธํฐ๋ ์ปจํ ์คํธ ์ ๋ณด๋ฅผ ์ ๋ฌ์ ๋ฐ๊ฒ ๋๋ค.
- ์ฆ, ์๋ธ๋ฆฟ์ด ์ต์ด ์์ฑ๋ ๋, ServletConfig ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด์ init() ๋ฉ์๋์ ์ ๋ฌ์ ํ๊ฒ ๋จ.
[ ServletConfig ]
package jakarta.servlet;
import java.util.Enumeration;
public interface ServletConfig {
String getServletName();
ServletContext getServletContext();
String getInitParameter(String var1);
Enumeration<String> getInitParameterNames();
}
- ServletConfig์ ์ญํ ์ ํด๋น ์๋ธ๋ฆฟ์ด ์ด๋ค ์๋ธ๋ฆฟ์ธ์ง, ๊ทธ๋ฆฌ๊ณ ์คํ์ ํ์ํ ์ด๊ธฐ ์ค์ ๊ฐ๋ค์ ๋ด๋ ์ญํ ์ ํด์ค๋ค.
- ๊ฐ๋จํ๊ฒ ์๋ธ๋ฆฟ ์ด๊ธฐ ์ค์ ์ ๋์์ค๋ค๊ณ ์๊ฐํ๋ฉด ๋๋ค.
- ์ฆ, ํด๋น ์ธํฐํ์ด์ค๋ ๊ตฌํ์ ํด์ init() ์ ๋ฃ์ด์ฃผ๊ฒ ๋๋ค๋ ์๋ฏธ์ด๋ค. ( Tomcat์ด ํด์ค )
(3) service(ServletRequest req, ServletResponse res)
- ํต์ฌ ๋ฉ์๋์ด๋ฉฐ, ์๋ธ๋ฆฟ์ด ํด๋ผ์ด์ธํธ ์์ฒญ์ ์ฒ๋ฆฌํ๋ ์ค์ง์ ์ธ ๋น์ฆ๋์ค ๋ก์ง ์ฒ๋ฆฌ๋ถ์ด๋ค.
- ์ฝ๊ฒ ๋งํด, ๋ชจ๋ ์์ฒญ์ service() ๋ก ๋ถํฐ ๋น์ฆ๋์ค ๋ก์ง์ผ๋ก ์ ๋ฌ์ด ๋๊ฒ ๋๋ค.
- init() ๋ฉ์๋๋ก ๋ง๋ค์ด์ง ์๋ธ๋ฆฟ์ service() ๋ฉ์๋๋ฅผ ํตํด ํด๋ผ์ด์ธํธ์ ์์ฒญ์ด ๋ค์ด์ฌ ๋๋ง๋ค ํธ์ถ์ด ๋๋ค.
(4) destroy()
- ์๋ธ๋ฆฟ์ด ๋ ์ด์ ํ์ ์๊ฑฐ๋, ์๋ฒ๊ฐ ์ข ๋ฃ๋๊ฑฐ๋, ์๋ธ๋ฆฟ์ ์ธ๋ก๋ ํ ๋ ํธ์ถ์ด ๋๋ค.
- ์ฝ๊ฒ ๋งํด, ์๋ธ๋ฆฟ์ด ๋ ์ด์ ํ์ ์์ด์ ์ข ๋ฃ๋๋ ์์ ์ ํธ์ถ๋๋ ๋ฉ์๋๋ผ ๋ณด๋ฉด ๋๋ค.
- ํด๋น ๋ฉ์๋๋ฅผ ์ ์ํ ๋ ๋ณดํต์ ์ค๋ ๋ ์ข ๋ฃ ๊ฐ์ ์์ ํด์ ์ฝ๋๋ฅผ ์์ฑ์ ํ๊ฒ ๋๋ค.
(5) ์ ๋ฆฌ
- Servlet API ๋ ์๋ธ๋ฆฟ ์๋ช ์ฃผ๊ธฐ๋ฅผ ์ ์ํ๋ฉฐ, ์ด ๊ตฌ์กฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ชจ๋ ์๋ธ๋ฆฟ์ด ๋์์ ํ๊ฒ ๋๋ค.
โ 3. HttpServlet
// HttpServlet
public abstract class HttpServlet extends GenericServlet {
}
// GenericServlet
public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {
}
- Servlet ์ธํฐํ์ด์ค๋ฅผ HTTP ๊ธฐ๋ฐ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ํนํ๋๋๋ก Servlet ์ ๊ตฌํํ ์ถ์ ํด๋์ค์ด๋ค.
- HttpServlet ์ถ์ ๋ฉ์๋๋ฅผ ๊ตฌํํจ์ผ๋ก์จ, ์๋ธ๋ฆฟ์ ๋ง๋ค์ด์ ์ด์ฉ์ ํ ์ ์๋ค. ( ์น ์์ฒญ์ ์์ ํด์ ์๋ต์ ๋ณด๋ผ ์ ์์ )
(1) HttpServlet ๊ตฌ์กฐ
// HttpServlet
public abstract class HttpServlet extends GenericServlet {
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
HttpServletRequest request;
HttpServletResponse response;
try {
request = (HttpServletRequest)req;
response = (HttpServletResponse)res;
} catch (ClassCastException var6) {
throw new ServletException(lStrings.getString("http.non_http"));
}
this.service(request, response); // ์ค๋ฒ๋ก๋ฉ ๋ service() ๋ฉ์๋ ํธ์ถ
}
}
- ํด๋น service() ๊ฐ Servlet API ๋ก ๋ถํฐ ๊ตฌํํ ๋ฉ์๋์ด๋ค.
- ๋ด๋ถ์ ์ผ๋ก this.service() ๋ฅผ ํตํด ์ค๋ฒ๋ก๋ฉ ๋ service() ๋ฅผ ํธ์ถํ๋ค.
[ service() - Overloading ]
// HttpServlet
public abstract class HttpServlet extends GenericServlet {
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getMethod();
long lastModified;
if (method.equals("GET")) {
lastModified = this.getLastModified(req);
if (lastModified == -1L) {
this.doGet(req, resp);
} else {
long ifModifiedSince;
try {
ifModifiedSince = req.getDateHeader("If-Modified-Since");
} catch (IllegalArgumentException var9) {
ifModifiedSince = -1L;
}
if (ifModifiedSince < lastModified / 1000L * 1000L) {
this.maybeSetLastModified(resp, lastModified);
this.doGet(req, resp);
} else {
resp.setStatus(304);
}
}
} else if (method.equals("HEAD")) {
lastModified = this.getLastModified(req);
this.maybeSetLastModified(resp, lastModified);
this.doHead(req, resp);
} else if (method.equals("POST")) {
this.doPost(req, resp);
} else if (method.equals("PUT")) {
this.doPut(req, resp);
} else if (method.equals("DELETE")) {
this.doDelete(req, resp);
} else if (method.equals("OPTIONS")) {
this.doOptions(req, resp);
} else if (method.equals("TRACE")) {
this.doTrace(req, resp);
} else {
String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[]{method};
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(501, errMsg);
}
}
}
- ๋ด๋ถ์ ์ผ๋ก Request ์ ๋ด๊ธด HTTP method ๋ฅผ ํ์ธ ํ ๋ค ์์ฒญ์ ๋ง๊ฒ doGet() ๋๋ doPost() ๋ฉ์๋๋ฅผ ํธ์ถ ํด์ค๋ค.
- ์ฆ, HttpServlet ์ ๊ตฌํํ ์๋ธ๋ฆฟ ํด๋์ค๋ค์ service() ๋ฉ์๋๋ฅผ ๊ฑด๋๋ฆด ํ์ ์์ด, doGet() ์ด๋ doPost() ๋ฉ์๋๋ง ์ค๋ฒ๋ผ์ด๋ฉํด์ ์์ฒญ์ ์ฒ๋ฆฌํด์ฃผ๋ฉด ๋๋ค. ์ด์ ๋, ๋ด๋ถ์ ์ผ๋ก HTTP method ๋ฅผ ๊ฒ์ฆํด์ ํด๋น ๋ฉ์๋๋ค์ ํธ์ถํ๊ธฐ ๋๋ฌธ์ด๋ค.
โ 4. DispatcherServlet
// DispatcherServlet - class
public class DispatcherServlet extends FrameworkServlet {
}
// FrameworkServlet - abstract
public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware {
}
// HttpServletBean - abstract
public abstract class HttpServletBean extends HttpServlet implements EnvironmentCapable, EnvironmentAware {
}
- DispatcherServlet ์ ์น ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ชจ๋ HTTP ์์ฒญ์ ๋ฐ์์ ์ ์ ํ ์ปจํธ๋กค๋ฌ๋ก ๋ถ๋ฐฐํ๋ ์ค์ ์ญํ ์ ํ๋ Spring MVC ํ๋ ์์ํฌ์ ํต์ฌ ์๋ธ๋ฆฟ์ด๋ค. ์ฆ, ํ๋์ ์๋ธ๋ฆฟ์ด๋ผ๋ ์๋ฏธ์ด๋ค.
- ๊ธฐ์กด์ ์๋ธ๋ฆฟ ๋ฐฉ์์ HttpServlet ์ถ์๋ฉ์๋๋ฅผ ๊ตฌํํด์ api ๋ง๋ค ์๋ธ๋ฆฟ์ ๊ฐ์ง๋ ๊ตฌ์กฐ ์์.
- ํ์ง๋ง, DispatcherServlet ์ ํ๋์ ์๋ธ๋ฆฟ์ ์ฑ๊ธํค ํจํด์ผ๋ก ๊ณต์ ํ๋ฉฐ, Controller ์ api ๋ฅผ ํธ์ถํ๋ ๊ตฌ์กฐ์ด๋ค.
- ์ฆ, Servlet ๋ง๋ค ํ์ผ์ด ์ถ๊ฐ ๋๋ ๋ฌธ์ ๋ฅผ DispatcherServlet ํ๋๋ก ๋ฌธ์ ๋ฅผ ํด๊ฒฐ ํ์.
- DispatcherServlet ์ ๋ด๋ถ์ ์ผ๋ก HttpServlet ์ถ์ ๋ฉ์๋๋ฅผ ๊ตฌํ์ ํ๊ณ ์์. ๊ฒฐ๋ก ์ HttpServlet ๊ธฐ๋ฐ
โ 5. Tomcat (ServletContainer)
- Tomcat ์ ์ํ์น ์ํํธ์จ์ด ์ฌ๋จ์์ ๋ง๋ ์๋ฐ ์๋ธ๋ฆฟ ์ปจํ ์ด๋์ด์ WAS(์น ์ ํ๋ฆฌ์ผ์ด์ ์๋ฒ) ์ด๋ค.
- Tomcat ์ ๋ด๋ถ์ ์ผ๋ก Servlet ์ ์์ฑ ๋ฐ ์ญ์ ๋ฅผ ํด์ฃผ๊ธฐ ๋๋ฌธ์ ServletContainer ๋ก๋ ๋ถ๋ฆฐ๋ค.
- ์ฆ, ์๋ธ๋ฆฟ์ ์๋ช ์ฃผ๊ธฐ์ธ init() / service() / destroy() ๋ฅผ ์ง์ ๊ด๋ฆฌํ๊ธฐ ๋๋ฌธ์ธ๊ฒ์ด๋ค.
[ ์ปจํ ์ด๋(Container)๋? ]
- ๊ฐ์ฒด์ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ด๋ฆฌํด์ฃผ๋ ํ๊ฒฝ ๋๋ ์์คํ ์ ์๋ฏธํ๋ค.
- ์ฝ๊ฒ๋งํด, ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ , ์ด๊ธฐํํ๊ณ , ์ฌ์ฉํ๊ณ , ํ๊ดดํ๋ ์ผ๋ จ์ ๊ณผ์ ์ ๊ด๋ฆฌํ๋ ๊ด๋ฆฌ์๋ฅผ ์๋ฏธํจ.
(1) Tomcat ์ญํ
- 1. HTTP ์์ฒญ์ ์์ ์ ํด์ HTTP ๋ฉ์์ง๋ก ๋ด๊ธด ๊ฐ๋ค์ ํ์ฑํด์ ๋น์ฆ๋์ค ๋ก์ง์ ์ ๋ฌ์ ํด์ฃผ๋ ์ญํ ์ ํ๋ค.
- 2. ๋ด๋ถ์ ์ผ๋ก Servlet ์ ์์ฑ ํด์ฃผ๊ณ , init() -> service() ๋ฅผ ํตํด์ ๋น์ฆ๋์ค ๋ก์ง์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ์ญํ ์ ํจ.
- 3. ๋ด๋ถ์ ์ผ๋ก ์ค๋ ๋ ํ์ ์ด์ํ๋ฉฐ, ๋ฉํฐ์ค๋ ๋๋ก ์์ฒญ ๋ง๋ค ์์ ์ค๋ ๋๋ฅผ ํ ๋นํด์ ์ฒ๋ฆฌ ํ๋ ์ญํ ์ ํด์ค.
- 4. ์ต์ข ์ ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ํด๋ผ์ด์ธํธ๋ก ์ ์ก์ ํด์ฃผ๋ ์ญํ ์ ํจ.
- ์ ๋ฆฌํ๋ฉด, Tomcat์ ์์ฒญ๊ณผ ์๋ต์ ๋ฐ์์ฃผ๋ ๋ฏธ๋ค์จ์ด์ ์ญํ ์ ํ๊ฒ ๋จ.