JSP(Java Server Page)
JSP는 웹에서 동적 문서에 해당하는 부분으로 Servlet의 종류 중 하나다.
앞에서 서블릿을 자세히 설명한 이유는 JSP와 동작 원리가 같기 때문이다.
JSP는 클라이언트가 동적페이지를 요청 했을 경우 웹서버에서 WAS에게 제어권을 넘기고 WAS가 서블릿 소스코드로 변환되고 서블리스 클래스로 컴파일 되어 응답하는 구조로 이루어져 있다.
앞서 서블릿을 공부하면서 불편한 부분이 많았을 것이다.
서블릿은 기본적으로 자바를 기본으로 html코드를 out.println()의 형태로 작성하는 구조이지만 JSP는 html코드를 기본으로 html문서 도중 java코드가 삽입 되어있는 형태이다.
따라서 해당 파트가 java문법임을 알려주는 태그(?)가 있다.
- <%! — — — %> : 변수 선언문으로 !와% 사이에 선언하고자 하는 변수를 작성하면 된다.
- <% — — — %> : 스크립트릿으로 %와%사이에 java코드 그대로 작성하면 된다. 주로 연산처리나 반복문 처리에 사용되게 된다.
- <% =— — — %> : 표현식으로 html문서 즉 웹에 바로 출력될 내용을 입력한다.
아래 코드 예제를 통해서 자세히 알아보자.
%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<%
String s = "String";
%>
<html>
<head>
<meta charset="UTF-8">
<title>hello</title>
</head>
<body>
<h2>Hello JSP</h2>
현재 날짜와 시간은 : <%=new java.util.Date() %><br>
<%= s %> 이러한 형태 또는 <%out.println(s); %>이와 같은 형태로 작성해면 된다.<br>
</body>
</html>
위와 같은 결과를 볼 수 있다. 여기서 소스를 직접 보면 우리가 코딩한것과 다른것을 볼 수 있다. 컴파일 시에 변수는 문자열 처리가 되어 작성 되었고 java코드 또한 바뀌어 컴파일 된것을 볼 수 있다.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>hello</title>
</head>
<body>
<h2>Hello JSP</h2>
현재 날짜와 시간은 : Tue Jun 09 18:15:38 KST 2020<br>
String 이러한 형태 또는 String
이와 같은 형태로 작성해면 된다.<br>
</body>
</html>
그렇다면 하는김에 좀 더 변수를 가지고 놀아보자
기본적으로 변수를 사용하려면 변수를 선언한 후에 사용하게 된다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>hello</title>
</head>
<body>
<h2>Hello JSP</h2>
현재 날짜와 시간은 : <%=new java.util.Date() %><br>
<%= s %> 이러한 형태 또는 <%out.println(s); %>이와 같은 형태로 작성해면 된다.<br>
<%
String s = "String";
%>
</body>
</html>
따라서 위와 같이 코딩하면 빨간 줄과 함께 코드에 문제가 있음을 확인할 수 있다.
하지만 우리는 변수를 선언하는 다른 선언문을 알고있다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>hello</title>
</head>
<body>
<h2>Hello JSP</h2>
현재 날짜와 시간은 : <%=new java.util.Date() %><br>
<%= s %> 이러한 형태 또는 <%out.println(s); %>이와 같은 형태로 작성해면 된다.<br>
<%!
String s = "String";
%>
</body>
</html>
이렇게 선언하면 아래와 같이 정상적으로 실행 됨을 알 수있다. 대체 어떻게 가능한 일인가 보자
이클립스 기준으로D:\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\myWeb\org\apache\jsp
해당 경로에 가면 JSP파일이 컴파일 된것을 볼 수 있다. 소스코드를 확인해보면 우리가 작성한 JSP파일이 자바의 형태로 바뀐것을 볼 수있다.
package org.apache.jsp.sample;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class hello_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports {
//변수 선언문으로 선언한 변수
String s = "String";
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;
}
}
//JSP 내장 객체
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\n");
out.write("<!DOCTYPE html>\r\n");
out.write("\r\n");
out.write("<html>\r\n");
out.write("<head>\r\n");
out.write("<meta charset=\"UTF-8\">\r\n");
out.write("<title>hello</title>\r\n");
out.write("</head>\r\n");
out.write("<body>\r\n");
out.write("\t<h2>Hello JSP</h2>\r\n");
out.write("\t현재 날짜와 시간은 : ");
out.print(new java.util.Date() );
out.write("<br>\r\n");
out.write("\t");
out.print( s );
out.write(" 이러한 형태 또는 ");
out.println(s);
out.write("이와 같은 형태로 작성해면 된다.<br>\r\n");
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에는 세 가지 주석이 있다.
- <! -- --> : html주석 html에서 사용하는 주석으로 JSP에서도 사용할 수 있다.
- <%-- --%> : JSP주석
- //, /* */ : JAVA주석
각각의 주석에는 차이가 있다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JSP File</title>
</head>
<body>
<h2>JSP Script 예제</h2>
<%
String scriptlet = "스크립트릿 입니다.";
String comment = "주석문 입니다.";
out.println("내장객체를 이용한 출력 : "+declation+"<br></br>");
%>
선언문 출력하기(변수) : <%=declation %><br></br>
<!-- JSP에서 사용하는 HTML 주석부분 -->
<!-- HTML 주석 : <%=comment%> --><br></br>
<%-- JSP 주석 : <%=comment%> --%><br></br>
<%
//자바 주석
/*
자바 여러줄 주석
*/
%>
<%!
String declation = "선언문 입니다.";
%>
<%!
public String declationMethod(){
return declation;
}
%>
</body>
</html>
위 코드를 실행시켜보면
주석 처리한 부분이 잘 되어있는것을 확인할 수 있다. 하지만 소스보기를 통해 확인 해 보면 아래와 같이 보임을 알 수 있다.
여기서 알 수 있는 점은
1. html주석은 소스보기를 통해 볼 수 있다.
2. JAVA주석은 소스를 볼 순 없지만 흔적이 남아있는것을 볼 수 있다.
3. JSP주석은 흔적도 소스도 남지 않는것을 볼 수 있다.
'FRONT > JSP' 카테고리의 다른 글
[Front] Servlet(서블릿)의 구조와 동작 원리 (0) | 2020.06.04 |
---|