Notice
Recent Posts
Recent Comments
Link
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
Tags
more
Archives
Today
Total
관리 메뉴

개발자입니다

[Java] 예제 소스 정리 - JSP 본문

네이버클라우드 AIaaS 개발자 양성과정 1기/DBMS, SQL, JDBC, Servlet

[Java] 예제 소스 정리 - JSP

끈기JK 2023. 2. 20. 19:38

eomcs-java\eomcs-servlet\app\src\main\webapp

 

 

예제 소스 정리

 

 

JSP 구동 원리
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ex01</title>
</head>
<body>
<h1>JSP 구동 원리</h1>
<pre>
1) 웹브라우저 ==> 서블릿 컨테이너 
   - JSP 실행 요청
     예) http://localhost:8080/java-web/jsp/ex01.jsp
2) 서블릿 컨테이너가 실행
   2.1 JSP의 서블릿 객체를 찾는다
   2.2 있으면,
     2.2.1 그 서블릿 객체를 호출한다. service() ---> _jspService()
   2.3 없으면,
     2.3.1 JSP 엔진을 이용하여 JSP 파일을 가지고 서블릿 자바 소스 파일을 생성한다.
     2.3.2 자바 컴파일러를 이용하여 소스 파일을 컴파일 한다.
     2.3.3 서블릿 객체를 생성한다. - init() 호출 ---> jspInit()
     2.3.4 그 서블릿 객체를 호출한다. - service() 호출 ---> _jspService()
   2.4 JSP 파일이 변경된 상태라면,
     2.4.1 다시 "2.3"을 반복한다.
3) 서블릿 컨테이너 ==> 웹브라우저 
   - 서블릿 실행 결과를 응답

JSP 파일을 가지고 생성한 서블릿 소스(.java)와 클래스 파일(.class)의 위치
- org.eclipse.wst.server.core/tmpx/work/...

정리!
- JSP 파일은 Python이나 PHP 처럼 직접 그 스크립트가 인터프리팅 되는 것이 아니다.
- JSP 엔진의 역할은 JSP 파일을 분석하여 서블릿 클래스를 생성하는 것이다.
- 즉 JSP 파일이 직접 실행되지 않는다!

JSP 
- 자바 서블릿 클래스를 만드는 재료로 사용된다.
- 그래서 서블릿 클래스를 만드는 "틀"이라 해서 "템플릿(template)"이라 부른다.
- JSP를 템플릿 기술이라 부르기도 한다.

JSP 공부법
- JSP를 작성할 때 사용하는 특정 태그들이 어떤 자바 코드를 생성하는지 이해하는 것이 중요하다.

JSP 실행을 요청하기
- JSP 파일이 있는 위치를 지정한다.
  예) http://localhost:8080/java-web/jsp/ex01.jsp

JSP를 변경한 후 실행을 요청하기
- 그냥 JSP 파일이 있는 위치를 지정하면 된다.
- 위에서 설명한대로 JSP 구동 원리에 따라 동작된다.

JSP 엔진이 서블릿을 만들 때 지켜야할 규칙:
- JSP 파일을 가지고 서블릿을 만들 때 HttpJspPage를 구현해야 한다.
- 클래스 계층도
  Servlet
    - init(ServletConfig):void
    - destroy():void
    - service(ServletRequest, ServletResponse):void
    - getServletInfo():String
    - getServletConfig():ServletConfig
    +---> JspPage
      - jspInit():void
      - jspDestroy():void
      +---> HttpJspPage
        - _jspService(HttpServletRequest, HttpServletResponse):void
        
</pre>
</body>
</html>

 

 

템플릿 데이터(template data)
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"
    trimDirectiveWhitespaces="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ex02</title>
</head>
<body>
<h1>템플릿 데이터(template data)</h1>
<pre>
- JSP 파일에 그냥 작성하는 텍스트는 자바 출력 코드를 생성한다.
- 예) 
  out.write("템플릿 데이터")
  out.print("템플릿 데이터")
</pre>
</body>
</html>

 

 

스크립트릿(scriptlet)과 JSP 주석<%out.print(i);%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" trimDirectiveWhitespaces="true"%>
<!DOCTYPE html>
<% // _jspService() 메서드에 안에 넣을 코드를 작성하라!
int i;
%>
<html>
<head>
<meta charset="UTF-8">
<title>ex03</title>
</head>
<%
i = 5;
%>
<body>
<h1>스크립트릿(scriptlet)과 JSP 주석<%out.print(i);%></h1>
<!-- 
  이것은 HTML 주석이다.
  JSP 엔진 입장에서는
  단지 출력문으로 바꿀 템플릿 데이터일 뿐이다. 
 -->
<%-- 
JSP 주석 
- 이 태그는 JSP 주석이다. JSP 엔진이 무시한다.
- 이 태그 안에 작성한 것은 자바 클래스를 생성할 때 제거된다.

스크립트릿
- JSP 파일 안에 실행할 자바 코드를 넣은 태그
- 예)
  <%  자바 코드 %>
- 스크립트릿 안에 작성한 코드는 자바 클래스를 생성할 때 
  _jspService() 메서드 안에 작성한 순서 그대로 복사된다. 
--%>
<%
if (i < 10) {
  for (int x = 0; x < i; x++) {
    out.println("<p>" + x + "</p>");
  }
}
%>
</body>
</html>

 

 

스크립트릿(scriptlet) 응용
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
String[] names = {"홍길동", "임꺽정", "유관순"};
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ex04</title>
</head>
<body>
<h1>스크립트릿(scriptlet) 응용</h1>
<ul>
<%
for (String name : names) {
  out.println("<li>" + name + "</li>");
}
%>
</ul>
</body>
</html>

 

 

표현식(expression element)
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
String[] names = {"홍길동", "임꺽정", "유관순"};
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ex05</title>
</head>
<body>
<h1>표현식(expression element)</h1>
<ul>
<%for (String name : names) {%>
<li><%=name%></li>
<%}%>
</ul>
</body>
</html>
<%--
용어 정리
1) 문장(statement)
   if () {...}
   else {...}
   for () {...}
   int a = 100;
   
2) 표현식(expression)
   - 문장 중에 값을 리턴하는 문장
   a * b        <---- 곱하기 결과 리턴
   (..)? a : b  <---- 조건에 따라 a 또는 b 값 리턴
   plus(10, 20) <---- plus()의 실행 값 리턴
   
   out.println("okok")  <---- 이 문장은 값을 리턴하지 않는다. 따라서 표현식이 아니다. 
 
표현식(expression element)
문법:
  <%= 표현식 %>
자바 코드:
  out.print(표현식)
  또는
  out.write(표현식)
--%>

 

 

선언부(declaration element)
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ex06 </title>
</head>
<%!
// 다음과 같이 상속 받은 메서드를 오버라이딩 할 수 있다.
public void jspInit() {
  System.out.println("ex06.jsp의 jspInit()");
}

public void jspDestroy() {
  System.out.println("ex06.jsp의 jspDestroy()");
}
%>
<body>
<h1>선언부(declaration element)</h1>

100,000,000 입금 = <%=calculate(100000000)%>
</body>

<%!
double interest = 0.025; // 인스턴스 변수

private String calculate(long money) { // 인스턴스 메서드 
  return String.format("%.2f", money + (money * interest));
}
%>

<%!
{ // 인스턴스 블록
  System.out.println("ex06 인스턴스 생성!");
}

static { // 스태틱 블록
  System.out.println("ex06 클래스 로딩");
}
%>
</html>
<%--
선언부
- 클래스에 멤버를 추가할 때 사용한다.
- jspInit()나 jspDestroy()와 같은 메서드를 오버라이딩 할 때도 사용할 수 있다.
- 선언하는 위치는 상관없다. 
- 문법:
    <%! 멤버 선언 %>
- 자바 코드:
  class JSP클래스 {
    
    멤버선언
    
    void _jspService() {
      ...
    }
  }
--%>

 

 

지시문(directive element)
<%@ page 
    language="java" 
    contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"
    import="java.net.Socket"
    import="java.net.ServerSocket"
    import="java.util.List,java.util.Map,java.util.Set"
    trimDirectiveWhitespaces="true"
    buffer="8kb"
    autoFlush="false"%>
<%@ page import="java.sql.Connection"%>
<%@ page import="java.sql.Statement"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ex07</title>
</head>
<body>
<h1>지시문(directive element)</h1>
<%
for (int i = 0; i < 1000; i++) {
  out.print(". "); 
}
%>
<p>출력완료!</p>
</body>
</html>
<%--
지시문
1) page
  - 서블릿 실행과 관련하여 특정 기능을 설정한다.
2) include
  - 다른 파일의 내용을 복사해온다.
3) taglib
  - JSTL 등 외부에서 정의한 태그 정보를 가져온다.
  
page 지시문
1) language="java"
   - JSP 페이지에서 코드를 작성할 때 사용할 언어를 지정한다.
   - 즉 <% 코드 %>, <%= 표현식 %>, <%! 코드 %> 태그에 코드를 작성할 때 사용할 언어이다.
   - 원래는 다양한 언어를 사용할 경우를 고려해 설계되었지만,
     현재는 java 언어만 사용 가능하다.
   - 이 속성은 생략해도 된다.

2) contentType="text/html; charset=UTF-8"
   - 다음 자바 코드를 생성한다.
       response.setContentType("text/html; charset=UTF-8");  

3) pageEncoding="UTF-8"
   - JSP 파일의 인코딩을 설정한다.
   - JSP 파일을 저장할 때 UTF-8로 저장한다면 위와 같이 선언하라.
   - 생략한다면 에디터에 설정된 문자집합으로 인코딩할 것이다.

4) import="java.net.Socket"
   - 자바의 import 문을 생성한다.
   - 사용법
     import="java.net.Socket"
       => 자바 코드: 
          import java.net.Socket;
     import="java.net.Socket,java.net.ServerSocket,java.util.List"
       => 자바 코드:
          import java.net.Socket;
          import java.net.Serversocket;
          import java.util.List;
   - 한 개의 page 지시문에 여러 개의 import를 작성할 수 있다.
   - 여러 개의 page 지시문을 작성할 수 있다.

5) trimDirectiveWhitespaces="true"
   - 지시문 끝에 줄바꿈 코드를 무시하고 싶을 때 사용한다.
   
6) buffer="8kb"
   - 출력 버퍼의 크기를 변경할 때 사용한다. 
   - 지정하지 않으면 기본이 8kb 이다.
   - 출력 내용이 버퍼의 크기를 넘으면 예외가 발생한다.
     서블릿에서는 자동으로 출력하였다. 
     그러나 JSP는 예외가 발생한다.

7) autoFlush="true"
   - 출력 버퍼가 찼을 때 자동으로 출력한다.
   - 기본은 true 이다.
   - false로 설정하면 출력 버퍼가 찼을 때 예외가 발생한다.
   
--%>

 

 

지시문(directive element) - include
<%@ page 
    language="java" 
    contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"
    trimDirectiveWhitespaces="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ex08</title>
</head>
<body>
<h1>지시문(directive element) - include</h1>
<%@ include file="./ex08_header.txt"%>
<p>테스트</p>
<%@ include file="./ex08_footer.txt" %>
</body>
</html>
<%-- 
include 지시문
1) file="JSP에 포함시킬 파일 경로"
   - 지정한 파일을 JSP로 포함시킨 후에 자바 서블릿 클래스를 생성한다.
     자동 생성된 자바 서블릿 클래스의 소스를 확인해보라!
   - 따라서 일반 텍스트 파일이면 된다. JSP 파일일 필요가 없다.
   - RequestDispatcher의 include()와 다르다.
   - 비록 JSP 파일이 아니더라도 다음을 선언하여 해당 파일의 문자집합을 지정해야 한다. 
       <%@ page pageEncoding="UTF-8"%>
     JSP 엔진에 해당 파일의 내용을 가져올 때 pageEncoding에 지정된 문자집합으로
     내용을 인식한다.
     또한 JSP 엔진은 <%@ page ...%>는 참고만 할 뿐 가져오지는 않는다. 
     
--%>

 

ex08_header

<%@ page pageEncoding="UTF-8"%>
<header>머리말</header>

 

 

ex08_footer

<%@ page pageEncoding="UTF-8"%>
<footer>꼬리말</footer>

 

 

지시문(directive element) - tablib
<%@ page 
    language="java" 
    contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"
    trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ex09</title>
</head>
<body>
<h1>지시문(directive element) - tablib</h1>
<c:forEach items="홍길동,임꺽정,유관순,안중근,윤봉길,김구,김원봉" var="n">
이름=<%=pageContext.getAttribute("n")%>, ${n}<br>
</c:forEach>
</body>
</html>
<%-- 
tablib 지시문
=> 외부에 따로 정의된 JSP 확장 태그를 가져올 때 사용한다.
=> JSP 확장 태그
   1) JSTL(JSP Standard Tag Library)
      - JSP 명세에 추가로 정의된 태그이다.
      - Servlet/JSP API에서는 JSTL 구현체를 제공하지 않는다.
      - 따로 구현된 라이브러리를 다운로드 받아야 한다.
        mvnrepository.com에서 JSTL 라이브러리를 검색하여 프로젝트에 추가하라.
      - 보통 apache.org 사이트에서 구현한 것을 사용한다.
   2) 개발자가 정의한 태그
      - 개발자가 따로 태그를 정의할 수 있다.
      - 그러나 실무에서는 유지보수를 일관성을 위해 JSTL과 같은 표준 API를 사용한다.
      - 즉 개발자가 자신의 회사에서만 사용할 태그를 따로 정의하지 않는다.

=> 사용법
      <%@ taglib 
          uri="확장 태그를 정의할 때 부여한 확장 태그 URI" 
          prefix="확장태그를 사용할 때 붙이는 접두사"%>
   JSP 페이지에서 사용하기
      <확장_태그_접두사:사용자_태그명 속성명="값" .../>
--%>

 

 

JSP 빌트인 객체 - JSP에서 기본으로 사용할 수 있는 객체
<%@ page 
    language="java" 
    contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"
    trimDirectiveWhitespaces="true" 
    isErrorPage="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ex10</title>
</head>
<body>
<h1>JSP 빌트인 객체 - JSP에서 기본으로 사용할 수 있는 객체</h1>
<%
// JSP에서 기본으로 준비한 변수를 사용할 수 있다.
request.setAttribute("aaa", "okok");
session.setAttribute("bbb", "nono");
application.setAttribute("ccc", "haha");
out.println("okok");
%>
</body>
</html>
<%--
JSP 빌트인 객체
- JSP를 가지고 서블릿 클래스를 만들 때 _jspService() 메서드에서 기본으로 준비하는 객체
- JSP 엔진은 반드시 다음과 같은 이름으로 레퍼런스를 선언해야 한다.
  즉 서블릿 컨테이너(ex: 톰캣, jetty, resin 등)에 상관없이 이름이 같다.

1) request - HttpServletRequest => _jspService() 파라미터이다.
2) response - HttpServletResponse => _jspService() 파라미터이다.
3) pageContext - PageContext => _jspService()의 로컬 변수이다.
4) session - HttpSession => _jspService()의 로컬 변수이다.
5) application - ServletContext => _jspService()의 로컬 변수이다.
6) config - ServletConfig => _jspService()의 로컬 변수이다.
7) out - JspWriter => _jspService()의 로컬 변수이다.
8) page - 서블릿 객체를 가리킨다. 즉 this 이다. => _jspService()의 로컬 변수이다.
9) exception - Throwable => _jspService()의 로컬 변수이다.
   - 이 변수는 JSP 페이지가 <%@ page isErrorPage="true"%>로 설정되었을 때만 존재한다.
   - 주로 오류가 발생되었을 때 실행되는 JSP 페이지인 경우 위 설정을 붙인다. 
 --%>

 

 

JSP 액션 태그 - jsp:useBean, jsp:setProperty
<%@page import="java.sql.Date"%>
<%@ page 
    language="java" 
    contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"
    trimDirectiveWhitespaces="true"%>
<%@ page import="com.eomcs.web.vo.Board"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ex11</title>
</head>
<body>
<h1>JSP 액션 태그 - jsp:useBean, jsp:setProperty</h1>
<%-- bitcamp.vo.Board 객체 생성하기 --%>
<jsp:useBean id="b1" class="com.eomcs.web.vo.Board" scope="page"/>
<%-- 
위 태그의 자바 코드:
com.eomcs.web.vo.Board b1 = (com.eomcs.web.vo.Board) pageContext.getAttribute("b1");
if (b1 == null) {
  b1 = new com.eomcs.web.vo.Board();
  pageContext.setAttribute("b1", b1);
}
--%>


<%-- scope을 생략하면 기본이 page(PageContext)이다. --%>
<jsp:useBean id="b2" class="com.eomcs.web.vo.Board"/>

<jsp:useBean id="b3" class="com.eomcs.web.vo.Board"/>

<%-- 객체의 setter 메서드를 호출하기 --%>
<jsp:setProperty name="b3" property="no" value="100"/>
<jsp:setProperty name="b3" property="contents" value="내용입니다."/>
<jsp:setProperty name="b3" property="viewCount" value="88"/>
<%-- 단, 자바 객체의 프로퍼티 타입이 자바 원시 타입과 문자열인 경우 가능하다.
     다른 타입이라면 따로 처리해야 한다. --%>
<%-- 
<jsp:setProperty name="b3" property="createdDate" value="2019-4-8"/>
--%>

<%=b1%> => out.print(b1);<br>  
<%=b2%> => out.print(b2);<br>
<%=b3%> => out.print(b3);<br> 
<%=b3.toString()%> => out.print(b3.toString());<br>

</body>
</html>
<%--
JSP 액션 태그
=> JSP에서 기본으로 제공하는 JSP 전용 태그
=> 따로 taglib를 사용하여 라이브러리를 선언할 필요가 없다.
=> JSP에서 기본으로 제공하기 때문에 그대로 사용하면 된다.
=> 네임스페이스 이름은 jsp 이다.
   <jsp:태그명 ..../>

jsp:useBean
=> JSP에서 사용할 객체를 생성할 때 사용할 수 있다.
=> 또는 보관소(ServletContext, HttpSession, ServletRequest, PageContext)에 
   저장된 객체를 꺼낼 때도 사용한다.
=> 사용법
     <jsp:useBean scope="보관소명" id="객체명" class="클래스명"/>   
=> 주요 속성
   scope
     - 객체를 꺼내거나 생성된 객체를 저장할 보관소 이름
     - 다음 4개의 값 중 한 개를 지정할 수 있다. 값을 지정하지 않으면 기본이 "page" 이다.
       application(ServletContext), session(HttpSession),
       request(ServletRequest), page(PageContext)
   id 
     - 객체를 꺼내거나 저장할 때 사용할 이름
   class
     - 보관소에서 객체를 찾을 수 없을 때 생성할 객체의 클래스명
     - 반드시 패키지 이름을 포함해 클래스명(fully-qualified name; FQName)을 지정해야 한다.
       <%@ page import="..."%> 를 선언해도 소용없다.
     - 객체를 꺼내는 경우 레퍼런스의 타입으로도 사용된다.
     - 객체를 생성할 때도 사용할 수 있기 때문에 반드시 콘크리트(concrete) 클래스명이어야 한다.
       추상 클래스와 인터페이스는 객체를 생성할 수 없기 때문에 안된다.
 --%>

 

 

JSP 액션 태그 - jsp:useBean (계속)
<%@ page 
    language="java" 
    contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"
    trimDirectiveWhitespaces="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ex12</title>
</head>
<body>
<h1>JSP 액션 태그 - jsp:useBean (계속)</h1>
<%-- 보관소에 저장된 객체 꺼내기 --%>
<%
application.setAttribute("s1", "홍길동");
session.setAttribute("s2", "임꺽정");
request.setAttribute("s3", "안중근");
pageContext.setAttribute("s4", "윤봉길");
%>

<jsp:useBean id="s1" type="java.lang.String" scope="application"/>
<%-- 자바코드로 표현해보면,
  String s1 = (String)application.getAttribute("s1");
 --%>
 
<jsp:useBean id="s2" type="java.lang.String" scope="session"/>
<%-- String s2 = (String)session.getAttribute("s2"); --%>

<jsp:useBean id="s3" type="java.lang.String" scope="request"/>
<%-- String s3 = (String)request.getAttribute("s3"); --%>

<jsp:useBean id="s4" type="java.lang.String" scope="page"/>
<%-- String s4 = (String)pageContext.getAttribute("s4"); --%>

<%=s1%><br>
<%=s2%><br>
<%=s3%><br>
<%=s4%><br>

<%-- 보관소에 없는 객체를 꺼내려 하면 예외 발생! --%>
<%-- 
<jsp:useBean id="s5" type="java.lang.String" scope="page"/>
--%>

</body>
</html>
<%--
jsp:useBean 문법:

<jsp:useBean id="레퍼런스명" type="레퍼런스타입" scope="보관소"/>
=> id
   - 보관소에서 값을 꺼낼 때 사용하는 이름이다.
   - 또한 꺼내 값을 저장하는 변수의 이름으로 사용된다.
=> type 
   - 보관소에서 꺼낸 객체의 타입을 지정할 때 사용한다.
=> scope
   - 값을 꺼내는 보관소를 가리킨다.
=> 예) 
태그: 
  <jsp:useBean id="s4" type="java.lang.String" scope="page"/>
자바코드: 
  String s4 = (String) pageContext.getAttribute("s4");
  if (s4 == null) {
    throw new Exception("객체 꺼내기 오류");
  }
 --%>

 

 

<%@page import="java.util.ArrayList"%>
<%@ page 
    language="java" 
    contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"
    trimDirectiveWhitespaces="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ex13</title>
</head>
<body>
<h1>JSP 액션 태그 - jsp:useBean (계속)</h1>
<%-- 보관소에 저장된 객체 꺼내기 --%>
<%
ArrayList<String> names = new ArrayList<>();
names.add("홍길동");
names.add("임꺽정");
names.add("안중근");
names.add("윤봉길");

pageContext.setAttribute("list", names);
%>

<jsp:useBean id="list" type="java.util.ArrayList<String>" scope="page"/>
<%-- 자바코드로 표현해보면,
  java.util.ArrayList<String> list = 
    (java.util.ArrayList<String>) pageContext.getAttribute("list");
  if (list == null) {
    throw new Exception("ArrayList 꺼내기 오류!");
  }
 --%>

<%
for (Object obj : list) {
  out.println(obj + "<br>");
}
%>

</body>
</html>
<%--
jsp:useBean (계속)
1) type 속성 
   - 보관소에서 꺼낸 객체의 타입을 지정할 때 사용한다.
 --%>

 

 

<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@ page 
    language="java" 
    contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"
    trimDirectiveWhitespaces="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ex14</title>
</head>
<body>
<h1>JSP 액션 태그 - jsp:useBean (계속)</h1>
<%-- 보관소에 저장된 객체 꺼내기 --%>
<%
ArrayList<String> names = new ArrayList<>();
names.add("홍길동");
names.add("임꺽정");
names.add("안중근");
names.add("윤봉길");

pageContext.setAttribute("list", names);
%>

<jsp:useBean id="list" type="java.util.List<String>" scope="page"/>
<%-- type에는 인터페이스를 지정할 수 있다.
  java.util.List<String> list = 
    (java.util.List<String>) pageContext.getAttribute("list");
 --%>

<%
for (String n : list) {
  out.println(n + "<br>");
}
%>

</body>
</html>
<%--
jsp:useBean (계속)
1) type 속성 
   - 보관소에서 꺼낸 객체의 타입을 지정할 때 사용한다.

 --%>

 

 

<%@ page 
    language="java" 
    contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"
    trimDirectiveWhitespaces="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ex15</title>
</head>
<body>
<h1>JSP 액션 태그 - jsp:useBean (계속)</h1>

<%-- id로 지정된 객체를 찾지 못하면 예외가 발생한다. --%>
<jsp:useBean id="list" type="java.util.List<String>" scope="page"/>
<%-- 자바코드로 표현해보면,
  java.util.List<String> list = 
     (java.util.List<String>) pageContext.getAttribute("list");
  if (list == null) {
    throw new Throwable("list라는 이름의 빈이 없습니다.");
  }
 --%>

<%
for (String n : list) {
  out.println(n + "<br>");
}
%>

</body>
</html>
<%--
jsp:useBean (계속)

1) type 속성 
   - 보관소에서 꺼낸 객체의 타입을 지정할 때 사용한다.

 --%>

 

 

<%@ page 
    language="java" 
    contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"
    trimDirectiveWhitespaces="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ex16</title>
</head>
<body>
<h1>JSP 액션 태그 - jsp:useBean (계속)</h1>

<%-- type 속성 대신에 class 속성을 사용하면 
     id로 지정한 객체를 찾지 못했을 때 해당 객체를 만들고,
     그 id로 보관소에 저장한다. 
     단 class 속성에는 generic 문법을 사용할 수 없다.
     또한 보관소에 객체가 없을 때 생성해야 하기 때문에 
     class 속성에는 인터페이스를 설정할 수 없다. --%>
<jsp:useBean id="list" class="java.util.ArrayList" scope="page"/>
<%-- 자바코드로 표현해보면,
  java.util.ArrayList list = 
     (java.util.ArrayList) pageContext.getAttribute("list");
  if (list == null) {
    list = new java.util.ArrayList();
    pageContext.setAttribute("list", list);
  }
 --%>

<%
// 제네릭 문법을 사용하지 못했기 때문에 list의 타입은 java.util.ArrayList이다.
// 따라서 for 문에서 항목의 타입을 지정할 때 String으로 지정할 수 없다.
out.println(list.size() + "<br>");
for (Object n : list) {
  out.println(n + "<br>");
}
%>

</body>
</html>
<%--
jsp:useBean (계속)

1) type 속성 
   - 보관소에서 꺼낸 객체의 타입을 지정할 때 사용한다.

 --%>

 

 

<%@ page 
    language="java" 
    contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"
    trimDirectiveWhitespaces="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ex16</title>
</head>
<body>
<h1>JSP 액션 태그 - jsp:useBean (계속)</h1>

<%-- id가 가리키는 객체가 보관소에 없을 때 
     class 속성에 지정된 타입의 인스턴스를 생성한다.
     그래서 class 속성에는 인터페이스나 추상 클래스를 지정할 수 없다.
     왜? 인터페이스나 추상클래스는 인스턴스를 생성할 수 없기 때문이다.--%>
<jsp:useBean id="list" class="java.util.List" scope="page"/>
<%-- 자바코드로 표현해보면,
  java.util.List list = 
     (java.util.List) pageContext.getAttribute("list");
  if (list == null) {
    list = new java.util.List(); <=== 이 부분 때문에 인터페이스를 지정할 수 없다.
    pageContext.setAttribute("list", list);
  }
 --%>

<%
// 제네릭 문법을 사용하지 못했기 때문에 list의 타입은 java.util.ArrayList이다.
// 따라서 for 문에서 항목의 타입을 지정할 때 String으로 지정할 수 없다.
for (Object n : list) {
  out.println(n + "<br>");
}
%>

</body>
</html>
<%--
jsp:useBean (계속)

1) type 속성 
   - 보관소에서 꺼낸 객체의 타입을 지정할 때 사용한다.

 --%>

 

 

<%@ page 
    language="java" 
    contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"
    trimDirectiveWhitespaces="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ex16</title>
</head>
<body>
<h1>JSP 액션 태그 - jsp:useBean (계속)</h1>

<%-- for ( : ) 문을 제대로 사용하려면 목록에 보관된 객체의 타입이 무엇인지 
     제네릭으로 지정해야 한다.
     그러나 class에서는 제네릭을 지정할 수 없다.
     해결책?
     - type과 class를 함께써라!
     - type으로 제네릭을 표현하고 class로 객체를 생성할 클래스를 지정하라! 
     --%>
<jsp:useBean id="list"
    type="java.util.List<String>"
    class="java.util.ArrayList" scope="page"/>
<%-- 자바코드로 표현해보면,
  java.util.List<String> list = 
     (java.util.List<String>) pageContext.getAttribute("list");
  if (list == null) {
    list = new java.util.ArrayList();
    pageContext.setAttribute("list", list);
  }
 --%>

<%
// type 속성에서 제레릭으로 String을 지정했기 때문에 항목의 타입을 String으로 선언할 수 있다.
//list.add(new Integer()); // 제네릭에 지정된 타입과 달라서 컴파일 오류!
list.add("홍길동");
list.add("임꺽정");
list.add("유관순");
list.add("안중근");

// ArrayList 에 제네릭을 적용하지 않으면 
// 다음과 같이 어떤 타입의 객체라도 저장할 수 있다.
// => 그러나 jsp:useBean 태그에서 type 속성을 설정하면 제네릭을 사용할 수 있다.
//list.add(new Integer(100));
//list.add(new com.eomcs.web.vo.Board());
 
for (String n : list) {
  out.println(n + "<br>");
}
%>

</body>
</html>
<%--
jsp:useBean (계속)

1) type 속성 
   - 보관소에서 꺼낸 객체의 타입을 지정할 때 사용한다.

 --%>

 

 

JSP 액션 태그 - jsp:include
<%@ page 
    language="java" 
    contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"
    trimDirectiveWhitespaces="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ex19</title>
</head>
<body>
<h1>JSP 액션 태그 - jsp:include</h1>

<jsp:include page="ex19_header.jsp"/>
<%-- 자바 코드:
RequestDispatcher rd = request.getRequestDispatcher("/ex19_header.jsp");
rd.include(request, response):
--%>

<p>테스트</p>

<jsp:include page="ex19_footer.jsp"/>
</body>
</html>
<%--
jsp:include
=> 다른 페이지로 실행을 위임한 후 그 실행 결과를 포함시킬 때 사용한다.
   실행이 끝난 후 제어권이 되돌아 온다.
=> 따라서 page 속성에 지정하는 URL은 서블릿/JSP 이어야 한다.
=> RequestDispatcher.include() 코드를 생성한다.

jsp:forward
=> 다른 페이지로 실행을 위임할 때 사용한다.
   제어권이 넘어가면 되돌아 오지 않는다.
=> 따라서 page 속성에 지정하는 URL은 서블릿/JSP 이어야 한다.
=> RequestDispatcher.forward() 코드를 생성한다.

 --%>

 

ex19_header.jsp

<%@ page 
    language="java" 
    contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"
    trimDirectiveWhitespaces="true"%>
<header>머리말</header>

 

ex19_footer.jsp

<%@ page 
    language="java" 
    contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"
    trimDirectiveWhitespaces="true"%>
<footer>꼬리말</footer>

 

 

errorPage 속성과 isErrorPage 속성
<%@ page 
    language="java" 
    contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"
    trimDirectiveWhitespaces="true"
    errorPage="ex20_error.jsp"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ex20</title>
</head>
<body>
<h1>errorPage 속성과 isErrorPage 속성</h1>
<%
int value = Integer.parseInt(request.getParameter("value"));
%>
10 / <%=value%> = <%=10 / value%>
</body>
</html>
<%--
errorPage
=> JSP를 실행하는 중에 오류가 발생했을 때 실행할 JSP를 지정할 수 있다.
=> 어떻게?
     <%@ page errorPage="URL"%>
=> 이 속성에 URL을 지정하지 않으면 오류가 발생했을 때 
   서블릿 컨테이너의 기본 오류 출력 페이지가 실행된다.
     
isErrorPage
=> 오류가 발생했을 때 실행되는 JSP 쪽에서
   그 오류 내용을 받을 때 사용한다. 
   

 --%>

 

<%@ page 
    language="java" 
    contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"
    trimDirectiveWhitespaces="true"
    isErrorPage="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ex20</title>
</head>
<body>
<h1>오류 발생!</h1>
<%=exception.getMessage()%>
</body>
</html>
<%--
오류가 발생했을 때 실행되는 JSP 페이지는 
exception이라는 변수를 통해 오류 내용을 받을 수 있다.
단, isErrorPage 속성이 true이어야 해당 변수가 준비된다.
 --%>