JSP가 어떻게 실행이 되는지 살펴보기로 하겠습니다.

서버에서 html 과 프로그램이 뒤섞여 있는 프로그램을 서버 측 스크립트(server side script) 라고 합니다. 유사한 형태로 PHP(PHP Hypertext Preprocessor) 와 ASP(Active Server Pages), 그리고 ASP.net 이 있습니다.

실행방식에는 크게 두 가지가 있는데, 한 줄 한 줄 실행되는 인터프리터 방식과 일단 파일을 컴파일해서 결과로 나온 파일(자바에서는 class라는 바이트코드형태)로 서비스하는 방식이 있습니다. ASP와 PHP는 전자이고, JSP와 ASP.net은 후자입니다.

JSP를 처음 호출할 때 느리게 느껴지는 이유가 바로 이 때문인데, 최초 호출시 컴파일되면 그 다음부터는 빠르게 실행됩니다.

컴파일은 두 가지 단계를 거칩니다.
1. JSP 파일을 서블릿(servlet)으로 변환(Translation) 하고
2. 이 서블릿을 class 파일로 컴파일

한 번 확인해 보겠습니다.
우리가 만들었던 파일의 흔적을 찾아보면 될 것입니다. 이 디렉토리에 가 보세요.

C:\Program Files\Apache Software Foundation\Tomcat 6.0\work\Catalina\localhost\_\org\apache\jsp

이 중에서 마지막에 만들었던 multiTableImport.jsp의 변환된 서블릿 multiTableImport_jsp.java 파일을 볼 수 있죠. 그리고 그 옆에는 고이 컴파일된 multiTableImport_jsp.class 가 있습니다.
multiTableImport_jsp.java 파일을 한 번 열어보겠습니다.

<소스 1> multiTableImport_jsp.java 내용
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import net.okjsp.study.Math;
public final class multiTableImport_jsp extends org.apache.jasper.runtime.HttpJspBase
  implements org.apache.jasper.runtime.JspSourceDependent {
  private static java.util.List _jspx_dependants;
  private javax.el.ExpressionFactory _el_expressionfactory;
  private org.apache.AnnotationProcessor _jsp_annotationprocessor;
  public Object getDependants() {
  return _jspx_dependants;
  }
  public void _jspInit() {
  _el_expressionfactory = JspFactory.getDefaultFactory().getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
  _jsp_annotationprocessor = (org.apache.AnnotationProcessor) getServletConfig().getServletContext().getAttribute(org.apache.AnnotationProcessor.class.getName());
  }
  public void _jspDestroy() {
  }
  public void _jspService(HttpServletRequest request, HttpServletResponse response)
       throws java.io.IOException, ServletException {
  JspFactory _jspxFactory = null;
  PageContext pageContext = null;
  HttpSession session = null;
  ServletContext application = null;
  ServletConfig config = null;
  JspWriter out = null;
  Object page = this;
  JspWriter _jspx_out = null;
  PageContext _jspx_page_context = null;
  try {
     _jspxFactory = JspFactory.getDefaultFactory();
     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\n");
     out.write("구구단입니다. <br />\r\n");
  // i: 단 변수
  for (int i = 2; i <= 9; i++) {
      // j: 곱수
      for (int j = 2; j <= 9; j++) {
     out.write('\r');
     out.write('\n');
     out.print( Math.getRow(i, j) );
     out.write('\r');
     out.write('\n');
      }  // end for j
     out.write("<hr />\r\n");
  } // end for i
     out.write('\r');
     out.write('\n');
  } catch (Throwable t) {
     if (!(t instanceof SkipPageException)){
       out = _jspx_out;
       if (out != null && out.getBufferSize() != 0)
         try { out.clearBuffer(); } catch (java.io.IOException e) {}
       if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
     }
  } finally {
     if (_jspxFactory != null) _jspxFactory.releasePageContext(_jspx_page_context);
  }
  }
}


오~, 뭔가 굉장히 복잡해 보이지 않습니까?
서블릿으로 변환된 JSP입니다. 스크립틀릿에 짜놓은 프로그램 부분도 보이고, 그것을 둘러싼 복잡한 코드들이 보입니다. 표현식으로 된 부분은 out.print() 라는 메소드의 인자로 들어가 있고, 엔터를 친 곳마다 out.write("\r"); out.write("\n"); 이 들어가 있습니다.

상단부터 살펴보면 package는 이전에 설명했기 때문에 넘어갑니다.
import 하는 부분이 나오는데, import javax.servlet.*; 는 javax.servlet 패키지 안에 있는 파일들을 참조하겠다는 것입니다. 파일에는 클래스와 인터페이스(interface) 들이 있습니다. 패키지는 디렉토리마다 고유성을 갖고 있습니다. "하위 디렉토리 모두 다 나와" 처럼 사용할 수는 없습니다. 콕 찝어서 import에 명시해주어야 합니다. 같은 디렉토리의 각각의 클래스를 명시할 수도 있고, 그 수가 많거나 귀찮을 경우 *를 써서 대표할 수도 있습니다.
import net.okjsp.study.Math; ㅎㅎ 우리가 import 한 것도 포함되어 있군요.

주욱 내려가서 try { ... } catch() {} finally {} 로 감싸져 있는 것이 보입니다.
때문에 JSP에서는 일반 자바처럼 예외처리를 하지 않아도 됩니다.

중요한 키워드들이 나옵니다. pageContext, application,config,session,out. 이것들은 JSP 안에서 사용되는 키워드들이기도 합니다. 일단 이런 것들이 있다 정도만 기억하십시오.

public void _jspService(HttpServletRequest request, HttpServletResponse response) 부분을 보겠습니다. 우리가 만든 JSP는 이 안에 모두 포함되어 있습니다. 한 메소드 안에 있다는 것이죠. 따라서 스크립틀릿에서 선언된 변수는 모두 지역변수(local variable)이 될 수 밖에 없는 운명입니다. 변수의 영향범위(scope)에 대해서는 후에 더 자세히 설명하겠습니다.
선언문에서 선언하는 변수나 메소드는 _jspService() 밖에 위치하게 됩니다.
앞으로 수도 없이 만나게 될 두 키워드가 나옵니다. request, response 요청과 응답.
request는 브라우저에서 보내온 정보들을 갖고 있고, response는 브라우저쪽에 보낼 결과정보를 담고 있습니다.

response.setContentType("text/html;charset=UTF-8"); 과 같이 결과로 브라우저에 보내지는 정보의 타입을 지정해서 보내줄 수 있습니다. text 타입이면서 html 형태를 가지고 있고, 문자셋은 UTF-8 이다 라는 것을 알 수 있습니다.

읽느라고 수고 많으셨습니다.
아직 끝이 아닙니다.
됐다구요. 어, 남은 거 아직 많은데...
일단 여기서 마치고, 다음은 JSP의 키워드들을 이용한 프로그램을 짜 보겠습니다.

+ Recent posts