β˜•οΈ Servlet & πŸ“‘ JSP

GunhoΒ·2024λ…„ 10μ›” 26일
1

Object Oriented Programming (OOP) & Java

λͺ©λ‘ 보기
10/29

β˜•οΈ Servlet

β˜•οΈ Servlet is a Java class responsible for accepting a request, processing it, and sending it back as a response.

A request in the Servlet almost always refers to an HTTP request and is specified as the HttpServletRequest interface. Similarly, a response is well defined as the HttpServletResponse interface in Java.

Servlet was historically devised to handle HTTP request and response by rendering the relevant responsive HTML codes inside the Java source codes.


🧸 Example

Below could be a good visualisation: HTTP message has two varying formats followed by a message being a request message or a response message.

ExampleServlet Class

public class ExampleServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // Set content type to text/html
        resp.setContentType("text/html");

        // Get the response writer to send HTML content back to the client
        PrintWriter out = resp.getWriter();

        // Generate a basic HTML response
        out.println("<html>");
        out.println("<head><title>Hello World Servlet</title></head>");
        out.println("<body>");
        out.println("<h1>Hello, World!</h1>");
        out.println("</body>");
        out.println("</html>");
    }
}

In-depth, for every Http request, service() method specified in the HttpServlet abstract class is invoked, and depending on the request's HTTP method, the request is dispatched to the doGet() method for GET requests and doPost() method for POST requests which becomes a further specification of the request handling methods.

Servlet then follows the identical steps to the Java source codes where the codes is compiled to the bytecode and JVM runs such bytecode (please read here).

πŸ“‘ JSP (Java Server Page)

πŸ“‘ JSP is a mechanism in which it generates an HTML page out of Java and HTML codes. Unlike, Servlet it can be viewed as the Java codes inside the HTML codes.

JSP was specifically introduced to address the inconveniences of generating the HTML codes within the Servlet class. JSP code has a file extension of .jsp and implicitly, JSP underlies the Servlet in which JSP is internally compiled into its Servlet tranformation by the Servlet Container then follows the same steps as the Servlet.


🧸 Example

Below could be a good practical example of how a JSP is transformed into a corresponding Servlet class.

Form JSP

<%@page contentType="text/html; charset=utf-8" %>
<html>
  <head><title>폼 생성</title></head>
  <body>
      <form action="/chap03/viewParameter.jsp" method="post"></form>
      이름: <input type="text" name="name" size="10"> <br>
  </body>
</html>

Form Servlet Class (from Form JSP)

/*
 * Generated by the Jasper component of Apache Tomcat
 * Version: Apache Tomcat/9.0.80
 * Generated at: 2024-10-20 04:39:17 UTC
 * Note: The last modified time of this file was set to
 *       the last modified time of the source file after
 *       generation to assist with modification tracking.
 */
package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;

public final class form_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent,
                 org.apache.jasper.runtime.JspSourceImports {

  private static final javax.servlet.jsp.JspFactory _jspxFactory =
          javax.servlet.jsp.JspFactory.getDefaultFactory();

  private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;

  private static final java.util.Set<java.lang.String> _jspx_imports_packages;

  private static final java.util.Set<java.lang.String> _jspx_imports_classes;

  static {
    _jspx_imports_packages = new java.util.HashSet<>();
    _jspx_imports_packages.add("javax.servlet");
    _jspx_imports_packages.add("javax.servlet.http");
    _jspx_imports_packages.add("javax.servlet.jsp");
    _jspx_imports_classes = null;
  }

  private volatile javax.el.ExpressionFactory _el_expressionfactory;
  private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;

  public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
    return _jspx_dependants;
  }

  public java.util.Set<java.lang.String> getPackageImports() {
    return _jspx_imports_packages;
  }

  public java.util.Set<java.lang.String> getClassImports() {
    return _jspx_imports_classes;
  }

  public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
    if (_el_expressionfactory == null) {
      synchronized (this) {
        if (_el_expressionfactory == null) {
          _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
        }
      }
    }
    return _el_expressionfactory;
  }

  public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
    if (_jsp_instancemanager == null) {
      synchronized (this) {
        if (_jsp_instancemanager == null) {
          _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
        }
      }
    }
    return _jsp_instancemanager;
  }

  public void _jspInit() {
  }

  public void _jspDestroy() {
  }

  public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
      throws java.io.IOException, javax.servlet.ServletException {

    if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
      final java.lang.String _jspx_method = request.getMethod();
      if ("OPTIONS".equals(_jspx_method)) {
        response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
        return;
      }
      if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
        response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
        response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP듀은 였직 GET, POST λ˜λŠ” HEAD λ©”μ†Œλ“œλ§Œμ„ ν—ˆμš©ν•©λ‹ˆλ‹€. JasperλŠ” OPTIONS λ©”μ†Œλ“œ λ˜ν•œ ν—ˆμš©ν•©λ‹ˆλ‹€.");
        return;
      }
    }

    final javax.servlet.jsp.PageContext pageContext;
    javax.servlet.http.HttpSession session = null;
    final javax.servlet.ServletContext application;
    final javax.servlet.ServletConfig config;
    javax.servlet.jsp.JspWriter out = null;
    final java.lang.Object page = this;
    javax.servlet.jsp.JspWriter _jspx_out = null;
    javax.servlet.jsp.PageContext _jspx_page_context = null;


    try {
      response.setContentType("text/html; charset=utf-8");
      pageContext = _jspxFactory.getPageContext(this, request, response,
      			null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

      out.write("\n");
      out.write("<html>\n");
      out.write("<head><title>폼 생성</title></head>\n");
      out.write("<body>\n");
      out.write("    <form action=\"/chap03/viewParameter.jsp\" method=\"post\"></form>\n");
      out.write("    이름: <input type=\"text\" name=\"name\" size=\"10\"> <br>\n");
      out.write("</body>\n");
      out.write("</html>");
    } catch (java.lang.Throwable t) {
      if (!(t instanceof javax.servlet.jsp.SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try {
            if (response.isCommitted()) {
              out.flush();
            } else {
              out.clearBuffer();
            }
          } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
        else throw new ServletException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}

βš™οΈ WAS (Web Application Server)

βš™οΈ WAS is a server specialised in rendering the dynamic web contents as a result of client-server interactions.

WAS can be also viewed as the web server combined with a component handling the business logics.

The server-side code is often represented as the business logic where the logic involves data manipulations and may include relevant database connection (not business logic).

βš™οΈ WAS strictly varies from the 🧷 Web Server where the Web Server is more centred on rendering static contents (HTML, CSS, JavaScript, and images) upon HTTP requests. Hence, even though βš™οΈ WAS can handle HTTP requests for static responses, for the sake of better performances and security reasons, web server often function as a proxy where the server forwards any requests involving the dynamic contents to the WAS and returns the generated response from the WAS.

NGINX is a popular web server, known for its high performance, scalability, and ability to handle static content, while Apache Tomcat, on the other hand, is a WAS that is specifically designed to run Java-based web applications. It can handle dynamic content generated by Servlets, JSP, and other Java EE technologies.

Below could be a good server side practical architecture where NGINX and Apache Tomcat are combined:

Tech Target Available at here


Tomcat internally employs a πŸ“¦ Servlet Container, which is responsible for managing the servlet lifecycle and processing client requests. The servlet container plays a critical role in handling Java Servlets and JSP files, which generate dynamic content in response to client requests.

The servlet container first checks if a corresponding servlet class exists to process the request. If it doesn't exist, the container dynamically generates a servlet Java file from the JSP file, compiles it, and creates a class file. This is part of the container's responsibility to translate JSPs into servlets, allowing the JSP to be treated like any other servlet-based web component.

Once the servlet class is available, the container manages its lifecycle. This involves three main phases: initialisation, execution, and destruction. During initialisation, the container creates an instance of the servlet class and invokes the init() method. In the execution phase, the container calls the service() method (or its specific variants like doGet() or doPost()) to handle incoming requests. Finally, when the servlet is no longer needed, the container invokes the destroy() method to release resources, marking the end of the servlet's lifecycle.

In addition to managing the servlet lifecycle, the container supports multithreading, allowing it to handle multiple client requests simultaneously by creating a new thread for each incoming request. This ensures that a single servlet instance can process multiple requests concurrently, increasing the efficiency and scalability of the application.


By offloading the complex task of request management, servlet lifecycle handling, and multithreading to the servlet container, developers can focus on implementing business logic, while the container ensures efficient request handling, security, and scalability for the web application.


πŸ“š References

JSP2.3 μ›Ή ν”„λ‘œκ·Έλž˜λ°
F-Lab (1)
F-Lab (2)
F-Lab (3)
Tech Target

profile
Hello

0개의 λŒ“κΈ€