22.08.08-Tomcat, JSP문법 구성, 서블릿 정의, 서블릿 접근 방법, JSP VS 서블릿, 서블릿 생명 주기
Tomcat
TomCat 과 편집기를 연동하기 위해서는 인스톨러 버전보다는 바이너리 버전으로 해야 한다.
https://tomcat.apache.org/download-90.cgi
JSP 와 톰켓 연결 과정
크라이언트가 jsp에 접속하려고 하면 tomcat에서는 jsp 영역만 실행하는데 html부분(javascript 포함)은 그냥 로드만 한다. 즉 javascript는 실행하지 않는다.
서버에서 jsp를 실행하고 나머지 부분인 html 부분이 클라이언트 브라우저로 넘어가서 실행된다. 이때 서버와 클라이언트와의 연결은 끊어진다.(HTTP프로토콜의 특징)
HTTP 프로토콜 : 무전기 방식 연결이 끊어졌다가 연결되었다가 한다. → 웹은 다운로드 기반이다.
코드
<%@ page contentType="text/html;charset=UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script>
var x = 5;
</script>
</head>
<body>
<%
int x= 10;
%>
this is my test jsp
</body>
</html>

클라이언트 영역,JSP부분이 사라져있다.
JSP문법 구성
- Java
- 자체 태그(< >)
- 내장 객체
- request
- response
- application
- 등등
JSP에서 지금까지 사용해왔던 내장 객체라 불리는 객체들의 실제 자료형은?
위의 질문에 답으로 하려면 request의 자료형을 알아야하고, 그러기 위해서는 jsp만으로는 설명이 안된다.
<%! 선언부%> 멤버영역을 말한다. 그런데 아무리 class는 아닌데 왜 멤버라 부르는가
왜 jsp에서는 try catch를 요구하지 않는가…
jsp는 javaEE의 기술을 많이 숨겨놓은 기술
서블릿(서버에서만 실행되는 언어)
TOMCAT에서 만든 JAVA 파일

/*
* Generated by the Jasper component of Apache Tomcat
* Version: Apache Tomcat/9.0.65
* Generated at: 2022-08-08 06:35:42 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 index_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports {
int price =5;
public int getPrice(){
return price;
}
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('\r');
out.write('\n');
out.write("\r\n");
out.write("<!DOCTYPE html>\r\n");
out.write("<html lang=\"en\">\r\n");
out.write("<head>\r\n");
out.write("<meta charset=\"UTF-8\">\r\n");
out.write("<title>Document</title>\r\n");
out.write("</head>\r\n");
out.write("<body>\r\n");
out.write("가격은 ");
out.print(getPrice());
out.write("\r\n");
out.write("</body>\r\n");
out.write("</html>\r\n");
} 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를 실행하면 TomCat에서 java파일을 생성하여 서블릿을 생성하는데 이는 서버에서만 실행되는 java class이다.
즉 JSP→ 서블릿으로 변경된다.
JSP란 사실 서블릿이라 불리는 즉 오직 서버에서만 해서 및 실행되어질 수 있는 javaEE의 클래스
java기술로 웹을 개발하려면 javaSE까지 터득해야하므로 진입장벽이 높은데 php,asp와 경쟁하려면 javaEE에서도 누구나 클래스를 몰라도 쉽게 쓸수 있는 스크립트 수준의 언어가 필요해서 jsp가 개발됨 따라서 여전히 기반 기술을 java
개발자가 jsp를 작성하면 실행시 jsp가 자동으로 톰켓과 같은 컨테이너의 의해 서블릿이라는 클래스로 변경되어 진다.
tomcat만 서블릿을 만들어지는 것이 아니라 개발자가 주도하여 서블릿을 개발 할 수있다.
서블릿은 직접 접근이 불가능 하다
접근 방법
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
<display-name>web0808</display-name>
<!--
web.xml이란?
일명 DD(Deployment Descriptor)라 불리며, 주 역할은 서버에 배포된 하나의 웹 어플리케이션에 대한 각종 설정을 담당
예) 서블릿의 매핑(mapping),어플리케이션과 관련된 이벤트, 인코딩....등
-->
<!-- 서블릿은 클래스이므로, 웹브라우저로 직접 접근할 수 없고, 또한 컴파일 결과물이 WEB-INF/classes에 위치하고, WEB-INF 특징상 보안된 디렉토리 이므로,
브라우저의 url로 직접 접근 불가능하다.. 따라서 서블릿을 실행하기 위해서는 DD내에서 클래스와 URL간의 간접 매핑을 통해 가능 -->
<servlet>
<servlet-name>testServlet</servlet-name>
<servlet-class>web0808.servlet.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>testServlet</servlet-name>
<url-pattern>/test</url-pattern><!-- 브라우저로 요청할 자원의 경로 -->
</servlet-mapping>
</web-app>
package web0808.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/*
톰캣만 서블릿을 작성할 수 있는것이 아니라 개발자도 작성할 수 있다.
extends : Is A 관계
1)상속 : 부모의 자원을 마치 내것 처럼 접근할 수 있는 것
2)자료형 : 부모와 같은 자료형이 되는 것
*/
public class MyServlet extends HttpServlet {//MyServlet은 서버에서 실행 될 수 있는 서블릿이다.
@Override
//클라이언트가 아무것도 명시하지 않고 요청을 할 경우 default는 GET방식으로 들어오게 되는데 GET방식의
//요청을 받는 서블릿의 메서드가 아래와 같은 doGet()메서드
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//jsp에서는 지시영역에서 작성하였지만, 우리가 정의한 서블릿에서는 response 객체로 처리=> 한글 처리
response.setContentType("text/html;charset=UTF-8");
PrintWriter out =response.getWriter();//응답정보 객체로 부터 출력스트림을 얻는다.
//문자 기반의 출력 스트림
out.print("안녕, 나의 서블릿에 의한 응답정보");//<%="안녕, 나의 서블릿에 의한 응답정보"%>와 같음
}
}
JSP vs Servlet
JSP
<%@ page contentType="text/html;charset=UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <table width="200px" border="1px"> <%for(int i=1; i<=9; i++){ %> <tr> <td><%="2*"+i+"="+(2*i) %></td> </tr> <%} %> </table> </body> </html>Servlet
package web0808.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class GuGuServlet extends HttpServlet { //Post등을 명시하지 않는한 기본적으로 브라우저의 요청은 디폴트가 GET방식이고 GET방식으로 들어온 요청은 doGet()메소드가 처리 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter();//문자기반의 출력 스트림 out.print("<table width=\"200px\" border=\"1px\">"); for(int i=1; i <=9; i++) { out.print("<tr>"); out.print("<td> 2*"+i+"="+(2*i)+"</td>"); out.print("</tr>"); } out.print("</table>"); } }
JSP가 아닌 서블릿을 직접 작성하여 사용할 경우 디자인 코드에 취약 너무 효율성이 떨어진다. 모든 html을 문자열 취급하여 쌍따옴표안에 넣어야한다. ⇒ 개발시 디자인 코드가 들어가지 않는 컨트롤러 등에 사용하기에 적당
Servlets의 생명주기
- 개발자가 서블릿을 개발하고 저장을 한 상태
- 클라이언트가 서버에 접속을 할때 서버에서 request객체(클라이언트 정보), response객체(응답정보), 스레드를 생성하고 서블릿(class상태, {init()처음에 생성되는 순간에만 ,service() 요청이 있는 상태마다 계속, destroy() }메소드가 있다. )으로 인스턴스를 생성하고 이때 init()메소드를 통해 초기화를 진행해서 인스턴스가 서블릿으로 동작하도록 한다.
- 서블릿에 request객체, response객체를 스레드가 service()메소드 안에 전달하고 이때 클라이언트에서 연결 방식이 GET,POST등 이냐에 따라 이 정보가 doGET(), doPOST()등으로 전달되어 수행된다.
- doXX() 중에는 response객체에 지속적으로 저장하면서 doXX()의 }를 만나면 이를 서버에 전달한다.
- service()메소드가 수행되면 수행 결과(response()메소드)를 다시 서버에 전달하고 전달받은 내용을 서버에서 재가공하여 이를 클라이언트에 전달한다.
- 클라이언트에 전달하면 서버는 클라이언트와의 연결을 끊고, 생성됐던 스레드, request,response를 제거한다.
- 이후 서버가 종료되면 서블릿의 destroy()메소드가 실행되어 죽는다.
'Program > JSP' 카테고리의 다른 글
| Cookie, Connection Pooling, EE → SE 재사용 (0) | 2022.12.25 |
|---|---|
| 웹 서버 VS 웹 컨테이너, 게시판 만들기 (0) | 2022.12.25 |
| 파일 업로드 (0) | 2022.12.25 |
| HTML 연동 (0) | 2022.12.25 |
| JSP란?, JSP 작성 영역, JDBC 적용 방법, 쿼리문 작성 방법 (0) | 2022.12.25 |