웹 어플리케이션 & WAS(Tomcat), JSP, Servlet

박영준·2024년 4월 23일
0

JSP

목록 보기
1/17

1. 웹 어플리케이션의 구조

1) 일반적인 논리적 구조

사용자 ----- Web Server ----- WAS ----- (DB)

  1. 사용자는 URL(또는 IP)를 통해 Web Server를 호출하고
    객체(reqeust)에 요청사항을 담아서 전송

  2. Web Server는 객체(request)를 받아서, 해당 객체를 바로 처리 or WAS(어플리케이션 서버)로 전송

  3. WAS는 객체(request)를 받아서 처리 후(필요시 DB 작업 진행)
    이에 대한 결과를 객체(response)에 담아서 회신(Web Server로)

  4. Web Server는 객체(response)를 회신(사용자에게로)

  5. 사용자의 브라우저가 응답받은 코드를 해석해서, 화면을 구성하여 출력

2) 단일 Web Server 구성

  • 가장 기본적인 홈페이지 구성

    • 구성 : html(뼈대), CSS(꾸미기), JavaScript(꾸미기. 동적 스크립트)
  • Web Server로 html, CSS, JavaScript를 보내면 브라우저가 이를 해석해서 실행하게 됨

  • 단점

    • 정적 페이지 구성
      • 단순히 페이지를 반환하기만 함
      • 필요한 페이지가 있다면, 미리 로직을 짜서 준비해둬야 함
      • 복잡한 로직이 들어간 페이지 모두를 사용자에게 전송해야 함

    정적 페이지만을 사용하는 것의 단점을 보완하기 위해 WAS 가 등장했다.

3) WEB - WAS 구성

  • 사용자의 reqeust를 받아서 짜여진 로직대로 처리한 후,
    웹 페이지를 만들어서 사용자에게 response

  • 역할 분리

    • Web

      • 정적 페이지 처리 (연산이 필요없는 것들, 이미지, 파일 ...)
      • 연산이 필요할 경우, WAS에게 객체를 넘겨서 연산을 수행하도록 하고 그 결과를 반환받기도 함
    • WAS

      • 동적 페이지 처리
  • 장점

    • 강력한 프로그래밍 언어(Java ...)를 사용해서 로직을 처리하기 때문에, 복잡한 로직 처리에 유리
    • Web Server가 주는 웹 페이지만 사용자가 처리하기 떄문에, 내부 로직을 알 수 없어서 보완 강화
    • Server단에서 복작한 연산을 해결하고 사용자에게는 결과값만 전송되기 때문에, 속도 향상 & 네트워크 부하 감소

    사용자와 서버 간 데이터를 주고 받는 일이 많아지면서, 이를 효율적으로 저장/편집하기 위해 DBMS가 개발되었다.

4) WEB - WAS - DB 구성

  • 장점 (DB에 주요 정보를 모아두는 것의)
    • 정보의 구조를 효율적으로 구성 할 수 있게 됨
    • DB에 사용자의 직접적인 접근을 막음으로써, 보안 강화

2. 정의

1) Servlet

writer.println("<html>");
		writer.println("<head>");
		writer.println("</head>");
		writer.println("<body>");
		writer.println("<h1>helloWorld~</h1>");
		writer.println("name : " + request.getParameter("name") + "<br/>");
		writer.println("id : " + request.getParameter("id") + "<br/>");
		writer.println("pw : " + request.getParameter("pw" + "<br/>"));
		writer.println("major : " + request.getParameter("major") + "<br/>");
		writer.println("protocol : " + request.getParameter("protocol") + "<br/>");
		writer.println("</body>");
		writer.println("</html>");
		writer.close();
  • .java 확장자 파일

  • Java의 일반적인 'class'와 동일한 개념

  • HttpServlet 클래스(JAVA EE에서 제공하는 서블릿 클래스. 웹을 다룰 수 있도록 해줌)를 상속받은 class

    예시처럼 스트림 객체를 생성해서 클라이언트에게 보내줄 html 코드를 전부 print 해줘야 함
    만약, 복잡한 레이아웃을 가진 페이지를 구성하려면 코드가 끝도 없이 더 길어지게 됨

    이런 불편함을 보완하기 위해 JSP 가 등장했다.

2) JSP

참고: JSP 란

3) Servlet Container

  • WAS = Servelt Container 역할

  • JSP 와 Servlet 을 구동하기 위함 (Web 환경에서 Servlet 이 구동될 수 있도록 함)

  • JSP --> Servlet 으로 바꿔서 실행

  • Servlet 의 생명주기 관리

  • WAS에서 여러 개의 Container를 구성해서 각각 독립적인 서비스로 구동시키는 것도 가능

  • Web Server에서 보내준 요청(request)을 가지고 thread를 생성한 후,
    필요한 jsp 또는 servlet 파일을 구동해서 로직을 수행하게 한 뒤,
    결과로 생성된 객체(response)를 Web Server에 보내주는 역할

4) Apache

구분

  • 아파치 : Web Server --> 웹서버 전용
  • 톰캣 : Web Application Server (WAS)

3. JSP와 Servlet

1) 흐름

  1. JSP 파일(.java)이 Servelt 파일(.java)로 변환됨

  2. Servelt 파일(.java)을 컴파일해서, .class 파일로 만든 후 실행

  3. 그 결과, 최종적으로 HTML 코드가 실행됨 (모든 Java 코드가 사라진)

처음 구동 시, 변환 과정이 한 번 더 있어 Servelt 만 사용하는 것에 비해 느리지만,
처음 구동하면서 .class 파일을 생성해두기 때문에, 두 번째 구동 시에는 변환&컴파일 과정 없이 진행돼서 Servelt 과 거의 동일한 속도로 작동하게 됨

2) 예시

JSP(.jsp) → Servlet(.java)으로 변환된 코드

/*
 * Generated by the Jasper component of Apache Tomcat
 * Version: Apache Tomcat/9.0.30
 * Generated at: 2020-02-12 15:41:55 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 Sample2_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=EUC-KR");
			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("\r\n");
			out.write("<!DOCTYPE html>\r\n");
			out.write("<html>\r\n");
			out.write("<head>\r\n");
			out.write("<meta charset=\"EUC-KR\">\r\n");
			out.write("<title>Insert title here</title>\r\n");
			out.write("</head>\r\n");
			out.write("<body>\r\n");
			out.write("\r\n");
			out.write('\r');
			out.write('\n');

			for (int i = 0; i < 10; i++) {
				out.println(i);
			}

			out.write("\r\n");
			out.write("\r\n");
			out.write("</body>\r\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);
		}
	}
}

JSP(.jsp) → Servlet(.java) → .class 파일 변환 후 최종적으로 사용자에게 전달된 코드

<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>


0
1
2
3
4
5
6
7
8
9


</body>
</html>

참고: Tomcat(톰캣), JSP, Servlet(서블릿)의 기본 개념 및 구조

profile
개발자로 거듭나기!

0개의 댓글