JSP 문법
JSP 문법 JSP란? JSP는 마이크로소프트의 ASP에 대항하기 위한 자바진영의 기술로, 서블릿의 가지고 있는 디자인과 코드의 분리의 어려움을 개선한 기술입니다. <body> <% out.println("Hello JSP Reader"); %> </body> </html> 보기에는 단순한 HTML 파일 같지만 사실 자바 코드를 포함하고 있습니다. 이제 이 파일을 클라이언트의 웹 브라우저에서 보기 위해 hello.jsp 로 우리가 만든 /bbs 디렉토리에 옮겨 놓으면 됩니다. 클라이언트가 hello.jsp를 요청하면, 서버는 .jsp 확장자를 인식하고 이것이 특별한 핸들링이 필요하다는 것을 판단하여 서블릿 컨테이너에게 이 파일을 보내게 됩니다. (이것은 웹서버와 PHP 파서와의 관계와 마찬가지입니다)
위의 간단한 예제도 결국은 서블릿으로 변환됩니다.
그리고 객체가 이미 로딩되었는지 확인합니다. 로딩이 되었다면 로딩된 객체가 서비스하고 로딩되지 않았다면 메모리에 로딩시킵니다. 소스가 변경되었다면 JSP엔진은 JSP소스를 다시 파싱하여 서블릿으로 변환합니다.
최초의 클라이어트가 접속하여 서비스를 요청할 때 컨테이너는 JSP 페이지가 서블릿으로 변환하고 서블릿을 컴파일하여 요청에 응답합니다. 일단 서블릿이 요청에 응답하면 메모리에 로딩되어 있는 상태로 다음 클라이언트의 요청을 기다리게 됩니다. ![]() ※ JSP도 서블릿 기반의 기술입니다. 이것은 JSP페이지의 전반적인 정보를 서블릿 엔진에게 제공합니다. 용법 : <%@ page {attribute="value"} %>
※ 디폴트 값이 적용되므로 개발자는 이 속성을 모두를 정의해 줄 필요가 없습니다.
예) <%@ include file="header.jsp" %> 상대경로 사용
태그라이브러리 지시어 속성 prefix 커스텀 태그 라이브러리를 구별하는데 쓰이는 Prefix 정의
Scripting
JSP Declarations는 JSP페이지가 첫번째로 로딩될때 초기화되고 그 후에 같은 페이지내의 다른 Declarations, expressions, scriptlets에게 이용되어 진다. 용법 : <%! declaration %> 변수 선언 예 : <%! String name = new String("BOB") %> Expressions JSP Expressions는 request타임에 .jsp 파일내에서 컨테이너에 의해 변환되어 삽입됩니다. 만약 결과값이 문자열로 변환되지 않는다면 번역시 에러가 발생합니다. 번역시 문자열이 검출되지 않는다면 ClassCastException 익셉션이 request타임에 발생합니다. 용법 : <%=expression %> 예) Hello <%= getName() %> Scriptlets 이들은 request타임에 실행됩니다. 용법 : <% scriptlets source %> Scriptlets를 가지고 있는 페이지를 처음 요청하면 JSP는 서블릿코드로 변환되고 컴파일되고 상주메모리에 로딩됩니다. <%...%>로 표현되는 Scriptlets는 서블릿의 service() 메소드내에 위치하게 됩니다. JSP Error 핸들링 JSP 아키텍처는 오로지 에러만을 다룰 수 있는 JSP페이지로서 에러 핸들링의 해법을 제시합니다.
JSP Error 페이지를 만드는 것은 간단하다. *** errorpage.jsp ***
<설명><%@ page isErrorPage="true" %>
<% if(true){ //Just throw an exception throw new Exception("An uncaght Exception"); } %> 에러페이지를 errorpage.jsp로 셋팅했다. 이렇듯 JSP페이지에게 에러페이지를 알리는 방법은 JSP페이지의 page directive에서 errorPage속성값을 정해주는 것입니다. 속성값에서 에러페이지의 위치는 페이지의 상대경로입니다. 이 예제을 실행해보기 위해서는 testerror.jsp 와 errorpage.jsp을 <TOMCAT_HOME>/webapps/bbs/에 위치시키고 testerror.jsp를 방문합니다. Implicit Objects ( 내장 객체 ) 내장 객체는 JSP문서내에서 이용되는 객체인데 특별히 레퍼런스를 얻기 위한 작업 없이 바로 사용할 수 있는 객체를 말합니다. out javax.servlet.jsp.JspWriter클래스의 인스턴스를 나타냅니다.
</body></html>request javax.servlet.http.HttpServletRequest 인터페이스의 인스턴스 리턴받습니다. *** request.jsp ***
response
사용자에게 리턴할 현재 응답을 나타낸다. pageContext jsp범위 내에서 이용 가능한 모든 자원 및 현재의 요청, 응답, ServletContext, HttpSession, ServletConfig 같은 페이지 속성들에 접근할 수 있는 방법을 제공합니다. pageContext 객체는 내장 객체를 접근할 수 있는 방법을 제공합니다. session 객체는 javax.servlet.http.HttpSession 객체를 나타냅니다.세션 데이타를 읽고 저장하는 데 사용됩니다.
이 객체는 주로 웹 컴포넌트가 공유할 수 있도록 ServletContext에 저장되어 있는 객체를 접근하기 위해 사용됩니다. config
page jsp페이지의 페이지 구현 클래스 인스턴스를 참조하며 Object형으로 선언되어 있습니다. page변수는 스크립팅 엘리먼트들 안에서 가끔 사용되며, 단순히 jsp페이지와 구현 서블릿 사이의 연결 역할을 합니다. exception
즉, 페이지디렉티브를 이용해서 에러 페이지로 지정한 jsp에서만 유용한 객체입니다. 표준 액션이란 미리 제공된 커스텀 태그라 생각하면 됩니다. 이 표준액션은 자바빈을 생성하거나 생성된 자바빈을 찾기 위한 액션입니다.
class : 객체의 구현을 정의하는 클래스 이 액션은 자바빈의 속성값을 셋팅하는 데 쓰입니다. propexpr name <jsp:useBean>에서나 다른 액션에서 정의된 인스턴스의 이름
셋팅을 원하는 곳의 속성
셋팅하기를 원하는 파라미터의 이름 value 빈의 속성에 대응하는 값 빈의 속성값을 가져와서 스트림으로 변환하고 이것을 output 스트림에 두는 액션 이 액션은 표준 액션, <jsp:include>,<jsp:forward>,<jsp:plugin>에 파람값을 전달할때 이용합니다.
이 액션은 JSP엔진이 실행중에 request를 다른 자원(정적 문서,서블릿, JSP)에게 넘기는 것을 가능하게 합니다.이 액션에서도 <jsp:param>가 쓰일 수 있는데 이는 포워딩할 대상자원에게 전달할 파라미터를 지정하기 위해 쓰입니다. 신택스 <jsp:forward page="relativeURL"> <jsp:param .../> </jsp:forward> 단일 속성 page는 포워딩할 대상자원을 상대주소로 나타낸 값입니다. <jsp:plugin> 이 액션은 다운로드나 애플릿,자바빈의 실행을 일으키는 HTML 코드를 생성하는데 사용됩니다.
서블릿컨텍스트와 웹 애플리케이션과의 관계에 대해 알기 전에 먼저 서블릿컨텍스트가 무엇인지 부터 알아야 합니다.
실제로 서블릿컨텍스트와 웹 애플리케이션과의 관계를 이해하기 위해,
*** ContextText.java *** package example; import javax.servlet.*; import javax.servlet.http.*; import java.io.*; import java.util.*; public class ContextTest extends HttpServlet{ private static final String CONTENT_TYPE="text/html;charset=euc-kr"; public void init() throws ServletException { } public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{ doPost(request,response); } public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{ // ServletContext 레퍼런스를 얻는다. ServletContext context=getServletContext(); // ServletContext로부터 count 속성값을 얻기를 시도합니다. Integer count=(Integer)context.getAttribute("count"); // 만약 count 속성이 없다면 만든다. // count 속성 초기값은 0 입니다. if(count==null){ count=new Integer(0); context.setAttribute("count",new Integer(0)); } response.setContentType(CONTENT_TYPE); PrintWriter out=response.getWriter(); out.println("<html>"); out.println("<head><title>ContextTest</title></head>"); out.println("<body>"); // count 속성값의 현재값을 출력합니다. out.println("<p>현재 COUNT 는 : "+count+".</p>"); out.println("</body></html>"); // doPost메소드가 불릴때마다 count 속성값을 1씩 증가시킨다. count=new Integer(count.intValue()+1); // ServletContext에 증가한 count 속성을 저장합니다. context.setAttribute("count",count); } public void destory(){ } }
코드 설명
ServletContext context = getServletContext(); 2. 서블릿컨텍스트의 레퍼런스를 얻었다면 서블릿컨텍스트로부터 count 속성값을 얻고자 시도합니다. 이때 getAttribute()메소드를 사용합니다. Integer count = (Integer)context.getAttribute("count"); 이때 setAttribute()메소드를 사용합니다.
count = new Integer(count.intValue() + 1); context.setAttribute("count", count);서블릿을 2개의 웹 애플리케이션에 배치합니다. 위 서블릿 코드를 bbs/WEB-INF/classes와 bbs2/WEB-INF/classes 에 위치시킨후 javac -d . ContextTest.java
라는 명령어로 컴파일하고
http://localhost/bbs/servlet/example/ContextTest http://localhost/bbs2/servlet/example/ContextTest
를 방문해 확인합니다.
파일위치 : /bbs/example/ , /bbs2/example/
<%@ page contentType="text/html;charset=euc-kr" %> <HTML><head><title>ContextTest</title></head><body> <h1> <% // count 속성을 얻기를 시도합니다. Integer count=(Integer)application.getAttribute("count"); // 만약 count 속성이 null이면 하나 만들어서 서블릿컨텍스트에 저장합니다. if(count==null){ count=new Integer(0); application.setAttribute("count",count); } %> 현재 COUNT 는 : <%=count%> <% // count 속성을 1 증가시켜 서블릿컨텍스트에 새로 저장합니다. count=new Integer(count.intValue()+1); application.setAttribute("count",count); %> </h1> </body></html> 이 파일을 bbs/example 와 bbs2/example 에 복사합니다. 각각의 분리된 웹 애플리케이션이 어떻게 이들 컴포넌트에 영향을 미치는지 확인합니다. 실험을 시작하기 위해 다음 URL를 방문합니다. http://localhost/bbs/example/ContextTest.jsp http://localhost/bbs2/example/ContextTest.jsp
http://localhost/bbs2/servlet/example.ContextTest
JSP 문법에서 꼭 확인해야 할 사항들
1. <%@ page session=true>
Q. page 지시자에서 session 속성은 구체적으로 무엇을 의미하는가? page 지시자에 session 속성이 false로 되어 있으면 웹 컨테이너에서는 해당 페이지가 session 객체를 생성하지도 못하고 또한 기존의 session 객체에 대한 레퍼런스도 얻을 수도 없습니다. false로 되어 있는 상태에서 session 객체에 접근하고자 하면 에러가 발생하게 됩니다. 2.<jsp:useBean id="name" scope="page|request|session|application" class=”ClassName” />
Q. 표준액션의 <jsp:useBean>에서 scope 속성은 무엇을 의미하는가? scope 속성은 jsp:useBean 속성 중에서 가장 중요한 부분입니다. 일단 이 속성은 자바 빈즈를 객체화시킨 후 어느 범위까지 사용을 할 것인지를 결정하는 것입니다. Scope 속성으로 지정한 영역의 수명에 따라서 빈 객체는 하나의 페이지가 아니라 여러 페이지에서 소멸하지 않고 참조되기고 합니다. (예를 들어 scope 속성이 session 으로 설정되었다면 빈 객체는 세션이 종료할 때까지 소멸되지 않고 유지됩니다.) 빈 객체가 생성된 이후 어떤 페이지에서도 참조될 수 없을 때 자동으로 소멸됩니다. Scope 속성은 기본 값은 page입니다. scope 속성에는 4개의 값을 지정해 줄 수 있는데 각각의 값에 대해서 정리하면 다음과 같습니다. page : 자바 빈즈가 현재의 JSP 페이지 내에서만 사용 가능하도록 설정할 때 기본 값이므로 특별히 지정하지 않으면 이 옵션이 적용됩니다. 빈 객체의 수명은 한 페이지 내에서만 유지됩니다. Page 영역으로 생성된 객체는 요청된 페이지 내에서만 유효합니다. 같은 페이지를 요청해도 새로운 빈 객체가 생성됩니다. 페이지의 실행 종료와 함께 빈 객체는 소멸됩니다. 매 페이지마다 새로 생성되므로 객체가 생성자의 초기화 부분을 항상 실행합니다. Page영역은 한 페이지에서만 유효하므로 <jsp:include> 태그나 <jsp:forward> 태그로 포함된 페이지에서 <jsp:useBean> 태그는 이미 만들어진 빈 객체를 참조하는 것이 아니라 같은 id 속성값을 가진 새로운 객체를 생성하게 됩니다. 또한 <jsp:include> 태그에서 생성한 빈 객체는 원 페이지에서 참조될 수 없습니다. Page 영역의 빈 객체는 jsp 페이지가 불릴 때마다 먼저 생성된 빈 객체의 상태가 필요하지 않고 새로 생성되어도 되는 경우에 적합하다. request : JSP 페이지는 jsp:forward, jsp:include 태그를 이용해서 다른 JSP 페이지와 함께 사용할 수 있는데 이 값으로 범위를 지정하면 현재의 JSP 페이지와 연결되어 있는 모든 JSP 페이지까지 영향을 미칩니다. 이럴 경우 이 자바 빈즈의 id는 다른 페이지에 동일한 이름의 id가 존재해서는 안됩니다. 반대로 page 속성으로 지정되어 있을 경우에는 현재 페이지에 jsp:forward와 jsp:include가 있을 지라도 해당 페이지까지 영향을 미치지는 않습니다. 즉, 해당 페이지가 원 페이지에서 참조하는 자바 빈즈를 참조하지 못합니다. 또한 request 영역으로 생성된 빈 객체를 request 객체에 저장하여 request 객체에서 찾아서 참조가 가능합니다. <jsp:include> 태그와 <jsp:forward>태그를 사용하는 경우 같은 request 객체를 사용하게 됩니다. session : 이 값으로 범위를 지정해 놓으면 세션에 유효할 때까지 자바 빈즈의 객체가 유효합니다. 세션이 유지되는 동안 같은 세션에서 호출되는 모든 페이지에서 빈 객체는 소멸되지 않고 유지됩니다. Session 영역으로 생성된 빈은 session 객체에 저장됩니다. 각 사용자에 대하여 독립적으로 생성되는 session 객체는 세션이 종료될 때까지 호출되는 모든 페이지에서 id 속성으로 구분되는 객체들을 유지하고 사용할 수 있게 해준다. 한가지 주의할 점은 page 지시자에서 session 속성을 false로 해 놓았을 경우에는 이 자바 빈즈 객체는 사용할 수 없게 됩니다. page,request scope 속성으로 생성된 빈은 브라우저의 요청에 대하여 결과를 생성하여 돌려준 다음에는 소멸됩니다. application : 이 값은 가장 광범위한 범위를 갖는 값입니다. 이 값으로 범위를 지정하면 모든 JSP 페이지에서 사용할 수 있으며 자바 빈즈 객체는 JSP 엔진을 정지시키거나 다시 시작시킬 때까지 계속 살아 있게 됩니다. 즉, JSP엔진에 의해 소멸되지 않고 유지됩니다. application scope 속성으로 생성된 빈은 application 내장객체에 저장되어 같은 웹 애플리케이션을 사용하는 모든 사용자에게 사용되어 질 수 있게 됩니다. 이 옵션은 거의 사용되지 않습니다. 3. <%@ include file=”상대경로파일명” %> 과 <jsp:include page=”상대경로파일명” /> 의 정확한 차이는? Include 디렉티브의 경우 포함되는 페이지와 현재 jsp 페이지가 합쳐져서 하나의 jsp 페이지(이는 곧 합쳐진 jsp페이지가 서블릿으로 변환됨을 의미)가 되는 반면에 <jsp:include>액션 태그로 포함되는 페이지와 포함하는 페이지가 합쳐지지 않고 그대로 존재하게 됩니다. | ||||||||||||||||||||||||