분류 전체보기

예전 작업 소스들

2009. 11. 11. 12:17
package net.jeongsam.prjpkg;
      import java.sql.Connection;
      import java.sql.PreparedStatement;
      import java.sql.ResultSet;
      import java.sql.SQLException;
      import java.util.ArrayList;
      import java.util.Iterator;
      import java.util.List;
      public class ContentDAO {
       private Connection conn = null;
       private PreparedStatement pstmt = null;
       private ResultSet rs = null;
       private String sql = null;
       
       private ContentDAO() {
        conn = ConnectionManager.getConnection();
       }
       
       public static ContentDAO getInstance() {
        return new ContentDAO();
       }
       
       /**
        * 글을 데이터베이스에 삽입한다. 이때 태그는 별도의 테이블에 목록을 만들어 저장한다.
        * 태그의 경우 리스트를 만들어 리스트의 목록을 차례대로 태그가 저장된 테이블의 데이터와 비교하여
        * 기존 태그의 카운트를 증가하거나 새로운 태그를 저장한다.
        * ※ 현재 구현만 해두었고 코드를 다듬어서 최적화시킬 필요가 있다.
        * @param content
        */
       public void insertArticle(ContentDomain content) {
        sql = "INSERT INTO cont (num, title, content, tag_list) ";
        sql += "VALUES (seq_cont.NEXTVAL, ?, ?, ?)";
        
        try {
         pstmt = conn.prepareStatement(sql);
         pstmt.setString(1, content.getTitle());
         pstmt.setString(2, content.getContent());
         pstmt.setString(3, content.getTags());
         pstmt.executeUpdate();
         
         Iterator tagList = content.toTagList().iterator();
         while (tagList.hasNext()) {
          String tag = tagList.next();
          sql = "SELECT tag_name FROM tag_list ";
          sql += "WHERE tag_name LIKE ?";
          pstmt = conn.prepareStatement(sql);
          pstmt.setString(1, "%" + tag + "%");
          if (pstmt.executeUpdate() > 0) {
           sql = "UPDATE tag_list SET tag_count = tag_count + 1 ";
           sql += "WHERE tag_name = ?";
           pstmt = conn.prepareStatement(sql);
           pstmt.setString(1, tag);
           pstmt.executeUpdate();
          } else {
           sql = "INSERT INTO tag_list (num, tag_name, tag_count) ";
           sql += "VALUES (seq_tag_list.NEXTVAL, ?, ?)";
           pstmt = conn.prepareStatement(sql);
           pstmt.setString(1, tag);
           pstmt.setString(2, "1");
           pstmt.executeUpdate();
          }
         }
        } catch (SQLException e) {
         e.printStackTrace();
        } finally {
         try {
          if (pstmt != null) pstmt.close();
          if (conn != null) conn.close();
         } catch (SQLException e) {
          e.printStackTrace();
         }
        }
       }
       
       public ContentDomain getArticle(int num) {
        // 데이터베이스에서 글 읽어오기
        return new ContentDomain();
       }
       
       public List getTagList() {
        // 데이터베이스에서 태그 목록 리턴
        return new ArrayList();
       }
       
       public static void main(String[] args) {
        ContentDomain article = new ContentDomain();
        ContentDAO cdao = getInstance();
        Iterator itrArticle = null;
        
        article.setTitle("두번째 글");
        article.setContent("테스트 글입니다.\n테스트 글입니다.");
        article.setTags("태그, test, 두번째글, second");
        
        itrArticle = article.toTagList().iterator();
        while (itrArticle.hasNext())
         System.out.println(itrArticle.next());
        cdao.insertArticle(article);
       }
      }

 /**
       * 문자열 컬렉션 타입 지정
       * 태그 배열을 파라메터로 받기 위해 선언
       */
      CREATE OR REPLACE TYPE type_tag_list IS TABLE OF VARCHAR2(100) NOT NULL;
      /**
       * 태그 배열을 파라메터로 받아서 태그 카운트를 갱신하거나
       * 신규 태그를 등록한다.
       */
      CREATE OR REPLACE PROCEDURE insert_tag (tags IN type_tag_list)
      IS
       idx INTEGER;
      BEGIN
       idx := tags.FIRST;     -- 컬렉션 인텍스 시작값으로 초기화
       LOOP
           EXIT WHEN idx IS NULL;   -- 컬렉션 데이터가 없으면 LOOP 빠져나감
             
              UPDATE tag_list     -- 태그가 존재하면 태그 카운트 증가
              SET tag_count = tag_count + 1
              WHERE tag_name = tags(idx);
             
              IF SQL%NOTFOUND THEN   -- UPDATE의 WHERE 조건 만족하는 row가 없을 때
               INSERT INTO tag_list  -- 태그 추가
         (num, tag_name, tag_count)
         VALUES (seq_tag_list.NEXTVAL, tags(idx), '1');
              END IF;
                                 
              idx := tags.NEXT(idx);
          END LOOP;
      END;

package net.jeongsam.prjpkg;
   import java.util.ArrayList;
      import java.util.Iterator;
      import java.util.List;
    import java.sql.CallableStatement;
      import java.sql.Connection;
      import java.sql.PreparedStatement;
      import java.sql.SQLException;
   import oracle.sql.ARRAY;
      import oracle.sql.ArrayDescriptor;
   public class ContentDAO {
       private ContentDAO() { }
       
       public static ContentDAO getInstance() {
        return new ContentDAO();
       }
       
       /**
        * 글을 데이터베이스에 삽입한다. 이때 태그는 별도의 테이블에 목록을 만들어 저장한다.
        * 태그의 경우 리스트를 만들어 리스트의 목록을 차례대로 태그가 저장된 테이블의 데이터와
        * 비교하여 기존 태그의 카운트를 증가하거나 새로운 태그를 저장한다.
        * @param content 글정보를 담은 JavaBean
        * @throws SQLException SQL Exception 처리
        */
       public void insertArticle(ContentDomain content) throws SQLException {
        Connection conn = null;
        PreparedStatement pstmt = null;
        CallableStatement cstmt = null;
        String query = null;
        String qproc = null;
        
        query = "INSERT INTO cont (num, title, content, tag_list) ";
        query += "VALUES (seq_cont.NEXTVAL, ?, ?, ?)";
        
        qproc = "{CALL INSERT_TAG(:TAGS)}";
        
        try {
         conn = ConnectionManager.getConnection();
         // 글을 추가한다.
         pstmt = conn.prepareStatement(query);
         pstmt.setString(1, content.getTitle());
         pstmt.setString(2, content.getContent());
         pstmt.setString(3, content.getTags());
         pstmt.executeUpdate();
         
         // 태그 목록을 갱신, 추가하기 위해 Oracle Procedure 호출
         cstmt = conn.prepareCall(qproc);
         ArrayDescriptor desc1 =
          ArrayDescriptor.createDescriptor("TYPE_TAG_LIST",conn);
         ARRAY input =
          new ARRAY(desc1, conn, content.toTagList().toArray());
         cstmt.setArray(1, input);
         cstmt.executeUpdate();
        } finally {
         if (pstmt != null) pstmt.close();
         if (cstmt != null) cstmt.close();
         if (conn != null) conn.close();
        }
       }
       
       public ContentDomain getArticle(int num) {
        // 데이터베이스에서 글 읽어오기
        return new ContentDomain();
       }
       
       public List<;string> getTagList() {
        // 데이터베이스에서 태그 목록 리턴
        return new ArrayList <string>();
       }
       /**
        * 클래스 테스트 코드
        * insertArticel() 메서드 테스트
        * @param args 미사용 파라메터
        */
       public static void main(String[] args) {
        ContentDomain article = new ContentDomain();
        ContentDAO cdao = getInstance();
        Iterator <string> itrArticle = null;
        
        article.setTitle("일곱번째 글");
        article.setContent("테스트 글입니다.\n테스트 글입니다.");
        article.setTags("일곱번째 글, 태그, 7th, example");
        
        itrArticle = article.toTagList().iterator();
        while (itrArticle.hasNext())
         System.out.println(itrArticle.next());
        try {
         cdao.insertArticle(article);
        } catch (SQLException e) {
         e.printStackTrace();
        }
       }
      } 


논리적 데이터베이스 모델링

데이터베이스 모델링은 개념적 데이터베이스 모델링과 논리적 데이터베이스 모델링, 물리적 데이터베이스 모델링의 3단계로 나눠볼 수 있습니다. 간단히 설명해보면,

  1. 개념적 데이터베이스 모델링 과정에서는 업무 분석 및 사용자 요구 분석을 통해 데이터베이스화 할 수 있는 형태, 즉, 엔티티(Entity)와 엔티티 타입(Entity type), 속성(Attribute)과 식별자(Identify), 엔티티 타입간의 관계(Relation) 등 설정하는 단계입니다.
  2. 논리적 데이터베이스 모델링 과정은 개념적 데이터베이스 모델링 과정을 통해 도출된 개념적 구조로부터 특정 DBMS가 처리할 수 있는 관계 스키마를 생성하는 단계입니다. 보통 실무에서는 논리적 데이터베이스 모델링, 줄여서 논리설계라고 하는 단계부터 바로 시작하기도 합니다. 개념적 데이터베이스 모델링의 경우 특정 DBMS와 상관없는 개념이지만 논리설계 과정에서는 관계형 데이터베이스와 같은 구체적인 데이터베이스 모델에 따른 설계를 진행합니다.
    관계형 데이터베이스를 기반으로 한 논리설계 단계에서의 주요 작업은 부모 테이블과 자식 테이블을 나누고 기본키(Primary key)와 외래키(Foreign key)의 설계와 식별(Identify) 관계와 비식별(Non-identify) 관계의 지정, 카디널리티(Cadinality)의 지정, 정규화 등의 과정을 거치게 됩니다.
  3. 마지막으로 물리적 데이터베이스 모델링이 있으며 물리설계라고도 합니다. 물리설계 과정은 MySQL이나 오라클과 같은 구체적인 벤더에 최적화된 설계를 진행하게 됩니다. 물리설계의 주요 과정으로는 데이터의 타입 및 제약 설계, 인덱스와 역정규화 설계외에 트리거 등의 설계가 있습니다.

기본키와 외래키, 그리고 식별과 비식별 관계, 카디널리티에 대해서는 이전 기사에서 설명하였으므로 이번 기사에서는 정규화에 대해 설명하도록 하겠습니다.

제 1 정규화

보통 논리설계 과정에서는 제 1 정규화와 제 2 정규화, 제 3 정규화 과정을 거치게 됩니다. 제 1 정규화의 목표는 반복되는 그룹 속성(attribute)의 제거입니다. 이를 위해 반복되는 그룹 속성을 별도의 테이블로 분리하고 부모 테이블의 기본키를 추가하여 1:M 관계를 형성하는 과정을 거치게 됩니다.

직업훈련생 정보를 저장하기 위해 다음과 같이 테이블을 설계하였다면,

등록번호(PK) 이름 주민번호 주소 전화번호 자격증 취득일
             

2개 이상의 자격증을 취득한 훈련생의 경우 주요 정보인 등록번호와 이름, 주민번호, 주소, 전화번호가 중복되게 됩니다. 이를 해결하기 위해 제 1 정규화를 적용하여 보겠습니다. 반복되는 그룹 속성인 이름, 주민번호, 주소, 전화번호를 제거하여 별도의 테이블로 만들고, 기본키인 등록정보를 외래키로 지정하여 자격증, 취득일을 남겨두어 기본정보가 저장된 테이블과 1:M 관계를 형성합니다.

기본정보 (부모 테이블)
등록번호(PK) 이름 주민번호 주소 전화번호
         

보조정보 (자식 테이블)
자격증취득번호(PK) 등록번호(FK) 자격증 취득일
       

또한 과정은 최대 6개의 교과목으로 구성되며 교과목 당 1개의 교재가 사용된다면 다음과 같이 테이블을 구성할 수 있습니다.

과정코드(PK) 과정명 과목1 교재1 과목2 교재2 과목3 교재3
               

이 경우 과목의 수가 3과목이 안된다면 Null이 발생하며, 넘는 경우 테이블의 컬럼을 추가하여야 하므로 좋은 설계가 될 수 없습니다. 이 역시 제 1 정규화의 대상이 됩니다.

제 2 정규화

제 2 정규화의 목표는 복합키의 사용시 복합키에 의존하지 않고 복합키의 일부분에 의존하는 컬럼들을 제거하는 것입니다. 직업훈련생의 평가정보를 저장하기 위해 다음과 같이 테이블을 설계하였습니다.

등록번호(PK) 과정코드(PK) 기간 평가결과
20090001 200901 6개월 A
20090002 200901 6개월 B
20090003 200902 3개월 A

위의 경우 등록번호와 과정코드가 함께 복합키이며 기본키로 지정되어 있습니다. 그러나 평가 결과의 경우 과정을 수강하는 훈련생의 평가이므로 복합키에 의존하는 반면 기간의 경우 과정코드에만 종속되어 있기 때문에 제 2 정규화를 통해 이를 해결할 수 있습니다.


제 3 정규화

제 3 정규화의 목표는 키본키에 의존하는 않고 일반 컬럼에 의존하는 컬럼들을 제거하는 것입니다. 다음과 같이 주문정보를 저장하였을 경우 고객명과 전화번호는 주문번호가 아닌 고객번호에 종속되어 있으므로 고객번호에 종속적인 컬럼들을 별도의 테이블로 분리시켜 새로운 테이블로 구성합니다.


데이터모델링의 주요 개념

데이터모델링의 세가지 주요 개념

  • Entity
  • Relation
  • Attribute

데이터모델링의 주요 개념은 엔티티와 관계, 속성의 세가지가 있습니다. 이번 시간에는 이 세가지 개념과 ERD(Entity Relation Diagram)를 그리는 방법을 배워보도록 하겠습니다.

1. 엔티티 타입 (Entity type)

업무에 필요하고 유용한 정보를 저장하고 관리하기 위한 것으로 영속적으로 존재하는 단위

엔티티 타입 = 엔티티의 집합

엔티티 = 엔티티 타입의 인스턴스

엔티티 타입은 다음과 같은 특징을 가지며 다음 성질을 만족하지 못하면 부적절한 엔티티 타입일 가능성이 높습니다.

첫번째는 설명한 바와 같이 업무에 필요하고 관리되어야 하는 정보를 말합니다. 예를 들어 학원 관리 시스템을 개발한다면 강사, 과목, 수강생 등이 엔티티 타입이 될 수 있습니다. 엔티티는 이러한 엔티티 타입이 구체화된 실체를 의미하며 홍길동 강사와 같이 개별 강사들이 될 수 있습니다.

두번째로 엔티티는 유일한 식별자에 의해 구별이 되어야 합니다. 강사 이름과 같은 엔티티는 동명 이인과 같이 구별이 힘든 경우가 있기 때문에 개별 엔티티를 구별하기 위해 주민등록번호 등과 같은 식별자에 의해 구별될 수 있습니다.

세번째로 엔티티 타입은 엔티티들의 집합이며 엔티티들을 대표할 수 있어야 합니다. 엔티티 타입은 엔티티들을 표현하는 논리적인 단위여야 합니다.

네번째는 엔티티 타입이 업무 프로세스에서 반드시 사용되어야 한다는 점입니다.

다섯번째는 엔티티 타입은 하나 이상의 속성 집합으로 이뤄진다는 특징이 있습니다. 예들 들어, 강사 엔티티 타입은 이름과 경력, 학력 등 다수의 속성들을 가지게 됩니다.

여섯번째 특징은 다른 엔티티 타입과 반드시 한 개 이상의 관계를 가져야 한다는 점입니다. 하지만 간혹 참조를 위해 관계를 생략하여 표현하는 경우도 있을 수 있습니다.

엔티티 타입은 관계형 데이터베이스 모델에서는 테이블로 표현할 수 있습니다.

엔티티 타입은 물리적인 형태의 유무에 따라 유형 엔티티 타입, 개념 엔티티 타입, 사건 엔티티 타입으로 분류합니다.

  • 유형(TANGIBLE) 엔티티 타입 - 강사, 강의실, 교재 등이 이에 해당됩니다.
  • 개념(CONCEPTUAL) 엔티티 타입 - 조직, 과목 등 물리적 실체보다는 개념적 정보로 구분할 수 있는 엔티티 타입입니다.
  • 사건(EVENT) 엔티티 타입 - 업무 수행을 발생하는 엔티티 타입으로 수강 신청, 수강료 입금 등이 해당됩니다.

그리고 발생 시점에 따라 기본 엔티티 타입과 중심 엔티티 타입, 행위 엔티티 타입으로 분류하기도 합니다.

  • 기본(FUNDAMENTAL) 엔티티 타입 - 업무의 가장 기본되는 정보로 다른 엔티티 타입과의 관계로 생성되지 않습니다.
  • 중심(MAIN) 엔티티 타입 - 기본 엔티티 타입에 의해 발생하는 엔티티 타입으로 기본 엔티티 타입인 수강생으로부터 수강 신청이라는 중심 엔티티 타입이 발생할 수 있습니다.
  • 행위(ACTIVE) 엔티티 타입 - 두개 이상 부모 엔티티에 의해 발생됩니다. 쇼핑몰에서 고객과 상품이라는 부모 엔티티로부터 주문이라는 행위 엔티티 타입을 도출할 수 있습니다.

2. 관계 (Relation)

관계란 두 개의 엔티티 타입 사이의 논리적인 관계를 말합니다. 관계를 표현할 때는 다음과 같은 요소를 고려합니다.

2.1 카디넬러티(Cadinality)

  • 1:1 (One To One) 관계 - 관계에 참여하는 엔티티는 각각 일대일로 대응됩니다.
  • 1:M (One To Many) 관계 - 관계에 참여하는 엔티티는 엔티티당 다수의 엔티티가 대응됩니다.
  • M:N (Many To Numerous) 관계 - 관계에 참여하는 엔티티은 양방향 모두 다수의 엔티티들이 대응됩니다.


2.2 참여도

  • 필수참여 관계(MANDATORY MEMBERSHIP) - 엔티티에 대해 반드시 대응되는 엔티티가 존재합니다.
  • 선택참여 관계(OPTIONAL MEMBERSHIP) - NULL을 허용하는 엔티티가 존재합니다.



3. 속성 (Attribute)

엔티티에서 더이상 분리할 수 없는 최소의 데이터 단위를 속성이라고 하며, 수강생 엔티티의 경우 수강생명, 주소, 전화번호 등이 속성이 될 수 있습니다.

3.1 속성의 특징에 따른 분류

  • 기본(Basic) 속성 - 업무 분석을 통해 정의된 속성 (예, 이름, 생년월일)
  • 설계(Design) 속성 - 원래 업무에 존재하지 않았으나 설계 과정에서 도출된 속성 (예, 등록번호, 구분코드)
  • 파생(Derived) 속성 - 다른 속성으로부터 계산이나 변형되어 생성된 속성 (예, 생년월일로부터 계산된 나이)

3.2 엔티티 구성에 따른 분류

  • 기본키(Primary key) 속성 - 엔티티 식별에 사용
  • 참조키(Foreign key) 속성 - 다른 엔티티와의 관계에 포함된 속성
  • 일반 속성 - PK, FK에 포함되지 않은 속성

4. 엔티티 수퍼 타입과 서브 타입

객체지향 언어에서의 상속과 비슷한 개념으로 일부 속성이나 관계를 제외하고 대부분이 동일한 여러 엔티티 타입을 한 개의 엔티티 수퍼 타입으로 묶어 통합하고 하나의 엔티티 타입안에 다른 엔티티 타입을 서브 타입으로 나누어 표기하기도 합니다.

개별 엔티티 타입의 동일한 속성들을 수퍼 타입으로 묶는 것을 엔티티 타입 통합이라고 하며 분석된 엔티티 타입에서 기능별로 여러 개의 엔티티 서브 타입으로 분화하는 것을 엔티티 타입 세분화라고 합니다.


5. 서브젝트 에리어

업무별로 연관이 많은 엔티티 타입을 그룹으로 묶어서 표시하는 개념을 서브젝트 에리어라고 합니다.


030-055 덤프 풀이

덤프 중 드래그 앤 드롭 문제 오류가 많아서 해답을 올려봅니다. 본 해답은 오류가 있을 수 있으며 직접 정오를 확인하시어 참고하시고 오류로 인한 불이익은 응시자 본인에게 있음을 밝혀둡니다. 문제 전체를 블로그로 게시하는 것은 무리가 있을 것 같아서 PPT 첨부 파일 올립니다.

Question 2.

Question 16.

일단 Q2.부터 Q118.까지 올립니다.

문서 객체 모델 (DOM)

노드의 추가와 삭제

자바스크립트의 사용시 다음 두가지 규칙을 지켜서 작성하는 것을 원칙으로 합니다. 무간섭 DOM 스크립트와 단계적 기능 축소의 원칙인데 무간섭 DOM 스크립란 HTML 코드와 자바스크립트를 완전히 분리하여 웹 브라우저의 제공 기능에 따라 다운그레이드나 업그레이드를 지원한다는 것입니다. 단계적 기능 축소는 자바스크립트를 지원하지 않는 웹 브라우저에서도 제공되는 기능을 이용할 수 있어야 한다는 의미입니다. 이 밖에 CSS에 의해 HTML에 여러가지 효과를 추가하는 것을 단계적 기능 확대라고 합니다. 다음 두 메서드는 단계적 기능 축소의 원칙에 위배된다는 이견이 있는 기능으로 HTML 구조를 바꾸기 때문에 이와 관련한 이슈꺼리를 제공하기도 합니다.

appendChild()와 removeChild()

부모 노드에 자식 노드를 추가하거나 삭제하는 기능으로 HTML의 특정 요소의 구조를 변경시킵니다. 노드를 추가하기 위해 document.createElement()와 document.createText() 메서드를 이용하여 엘리먼트 노드나 텍스트 노드를 생성합니다. 다음은 이를 이용한 예제입니다.

<!-- dom_api.html --> <?xml version="1.0" encoding="UTF-8" ?> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>노드 추가하여 DB에 저장하는 예</title> <script type="text/javascript"> function addInputItem() { var root = document.getElementsByTagName("tbody")[0]; // tbody에 tr DOM 트리 추가 var element = document.createElement("tr"); element.appendChild(document.createElement("td")); var eInput = document.createElement("input"); eInput.setAttribute("type", "text"); eInput.setAttribute("name", "text"); eInput.setAttribute("size", "20"); element.firstChild.appendChild(eInput); root.appendChild(element); } function removeInputItem() { var nodes = document.getElementsByTagName("tr"); // tr 태그들을 찾아 tfoot의 tr과 tbody의 첫번째 tr은 유지하고 마지막 tr부터 삭제 var root = nodes[1].parentNode; if (nodes.length > 2) root.removeChild(root.lastChild); } </script> </head> <body> <h1 align="center">문자열 저장</h1> <form method="post" action="action.jsp"> <table align="center"> <tfoot> <tr><td align="center"><input type="submit" value="저장하기" /></td></tr> </tfoot> <tbody> <tr> <td> <input type="text" name="text" size="20" /> <input type="button" value="항목 추가" onclick="addInputItem()" /> <input type="button" value="항목 삭제" onclick="removeInputItem()" /> </td> </tr> </tbody> </table> </form> </body> </html>

<!-- action.jsp 스크립틀릿과 표현식 이용하여 폼의 내용 출력 -->
<?xml version="1.0" encoding="UTF-8" ?>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<% request.setCharacterEncoding("UTF-8"); %>
<% String[] values = request.getParameterValues("text"); %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>파라메터 출력</title>
</head>
<body>
<h1>파라메터 출력</h1>
<table>
<% for (int i = 0; i < values.length; i++) { %>
<tr><td><%= values[i] %></td></tr>
<% } %>
</table>
</body>
</html>
package <!-- 폼의 데이터를 저장할 빈 -->
net.jeongsam;

public class Bean091013b {
	private String[] text;

	public String[] getText() {
		return text;
	}

	public void setText(String[] text) {
		this.text = text;
	}
	
	public int size() {
		return text.length;
	}
}
<!-- action.jsp 액션태그와 표현언어(EL), JSTL 이용 -->
<?xml version="1.0" encoding="UTF-8" ?>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<% request.setCharacterEncoding("UTF-8"); %>
<jsp:useBean id="formBean" class="net.jeongsam.Bean091013b" />
<jsp:setProperty property="*" name="formBean" />
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Insert title here</title>
</head>
<body>
<h1>파라메터 출력</h1>
<table>
<c:forEach var="text" items="${formBean.text}">
	<tr><td><c:out value="${text}" /></td></tr>
</c:forEach>
</table>
</body>
</html>

+ Recent posts