ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JSP] 010. JDBC 연동 게시판 작성 실습
    SsY/Class 2023. 6. 2. 10:00
    728x90
    JDBC 연동 게시판 작성 실습
    - WebApp20
    ■■■ JDBC 연동 게시판 작성 실습 ■■■
    
    ○ 프로젝트 : WebApp20
    
    ○ 프로젝트 성격 : JDBC 연동 JSP 게시판 구성 (Model 1 방식)
    
    ○ 물리적 구성 요소
    
    	- WebApp20_scott.sql
    	- WebApp20_scott(plsql).sql
    	
    	- DBConn.java
    	- BoardDTO.java
    	- BoardDAO.java
    	- MyUtil.java	// 게시판 페이징 처리  ◀ 1 | 2 | 3  | ... |  ▶  ★주의★
    	
    	- List.jsp
    	- Created.jsp
    	- Created_ok.jsp
    	- Article.jsp
    	- Updated.jsp
    	- Updated_ok.jsp
    	- Delete_ok.jsp
        
            ++ 추가 됨
            - created.css
            - list.css
            - style.css
            - util.js

    ※ 해당 방식 (즉, Model 1 방식) 에서는 Delete_ok.jsp 페이지로 강제로 속성값을 넘겨주면 삭제된다.
        이후에, MVC (Model 2 방식) 을 사용한다면 클라이언트가 직접 페이지로 접근이 불가능하게 만들 수 있다.

    • WebApp20_scott.sql
    더보기
    SELECT USER
    FROM DUAL;
    --==>> SCOTT
    -------------------------------------------------------------------------------------------------------------------------------------------------
    -- ○ 기존 테이블 제거
    DROP TABLE TBL_BOARD PURGE;
    --==>> Table TBL_BOARD이(가) 삭제되었습니다.
    -------------------------------------------------------------------------------------------------------------------------------------------------
    -- ○ TBL_BOARD 테이블 생성 (게시판 전용 테이블)
    CREATE TABLE TBL_BOARD
    ( NUM       NUMBER(9)                   NOT NULL    -- 게시물 번호
    , NAME      VARCHAR2(30)                NOT NULL    -- 게시물 작성자  // 회원가입 연동시 - ID 로 식별
    , PWD       VARCHAR2(20)                NOT NULL    -- 게시물 암호    // 회원가입 연동시 - 암호 필요X
    , EMAIL     VARCHAR2(50)                            -- 게시물 이메일
    , SUBJECT   VARCHAR2(100)               NOT NULL    -- 게시물 제목
    , CONTENT   VARCHAR2(4000)              NOT NULL    -- 게시물 내용   // 첨부파일, 스마트에디터 구성 시 별도로 테이블 생성하는 경우도 많다.
    , IPADDR    VARCHAR2(20)                            -- 접속한 클라이언트 IP 주소  // 작성자의 IP 
    , HITCOUNT  NUMBER      DEFAULT 0       NOT NULL    -- 게시물 조회수  // 최근에는 로그 기록(별도의 로그 테이블 생성하여)으로 확인
    , CREATED   DATE        DEFAULT SYSDATE NOT NULL    -- 게시물 작성일  //-- 업무정책상 : 최초 입력일, 최총수정일 등...
    , CONSTRAINT BOARD_NUM_PK PRIMARY KEY(NUM)          -- 게시물 번호에 PK 제약조건 설정
    );
    --==>> Table TBL_BOARD이(가) 생성되었습니다.
    -------------------------------------------------------------------------------------------------------------------------------------------------
    -- ○ 게시물 번호의 최대값을 얻어내는 쿼리문 구성 (시퀀스 대신)
    SELECT NVL(MAX(NUM),0) AS MAXNUM
    FROM TBL_BOARD;
    --> 한줄 구성 
    SELECT NVL(MAX(NUM),0) AS MAXNUM FROM TBL_BOARD
    ;
    -------------------------------------------------------------------------------------------------------------------------------------------------
    -- ○ 게시물 작성 쿼리문 작성
    INSERT INTO TBL_BOARD(NUM,NAME,PWD,EMAIL,SUBJECT, CONTENT, IPADDR, HITCOUNT, CREATED)
    VALUES(1,'깡벼리','1234', 'test@gmail.com', '작성테스트', '게시물내용 작성', '211.238.142.48', 0 , SYSDATE);
    --> 한 줄 구성
    INSERT INTO TBL_BOARD(NUM,NAME,PWD,EMAIL,SUBJECT, CONTENT, IPADDR, HITCOUNT, CREATED) VALUES(1,'깡벼리','1234', 'test@gmail.com', '작성테스트', '게시물내용 작성', '211.238.142.48', 0 , SYSDATE)
    ;
    --==>> 1 행 이(가) 삽입되었습니다.
    -------------------------------------------------------------------------------------------------------------------------------------------------
    -- ○ 롤백
    ROLLBACK;
    --==>> 롤백 완료.
    -------------------------------------------------------------------------------------------------------------------------------------------------
    -- ○ DB 레코드의 갯수를 가져오는 쿼리문 구성 -- 게시물의 갯수 확인 (페이징 시에 갯수 제한)
    SELECT COUNT(*) AS COUNT 
    FROM TBL_BOARD;
    --> 한 줄 구성 
    SELECT COUNT(*) AS COUNT FROM TBL_BOARD
    ;
    -------------------------------------------------------------------------------------------------------------------------------------------------
    -- ○ 특정 영역의 (시작번호 ~ 끝번호) 게시물 목록을 읽어오는 쿼리문 구성
    --    번호, 작성자, 제목, 조회수, 작성일
    --    (List.jsp)
    SELECT NUM, NAME, SUBJECT, HITCOUNT, TO_CHAR(CREATED,'YYYY-MM-DD') AS CREATED
    FROM TBL_BOARD
    WHERE NUM>=1 AND NUM <=10;
    --==>>
    /*
    1	이길동	날씨에 대해 작성한 게시물1	70	2023-05-20
    3	박길동	음식에 대해 작성한 게시물3	20	2023-05-20
    6	박길동	음식에 대해 작성한 게시물6	20	2023-05-20
    7	최길동	운동에 대해 작성한 게시물7	10	2023-05-20
    9	박길동	음식에 대해 작성한 게시물9	20	2023-05-20
    10	홍길동	취미에 대해 작성한 게시물10	30	2023-05-20
    */
    
    SELECT NUM, NAME, SUBJECT, HITCOUNT, CREATED, CONTENT, IPADDR
    FROM
    (
        SELECT ROWNUM AS RNUM, DATA.*
        FROM
        (
            SELECT NUM, NAME, SUBJECT, HITCOUNT, IPADDR, CONTENT, TO_CHAR(CREATED,'YYYY-MM-DD') AS CREATED
            FROM TBL_BOARD
            ORDER BY NUM DESC
        ) DATA
    )
    WHERE RNUM >= 1 AND RNUM <= 10;
    --==>>
    /*
    673	이길동	날씨에 대해 작성한 게시물673	70	2023-05-20
    672	박길동	음식에 대해 작성한 게시물672	20	2023-05-20
    671	이길동	날씨에 대해 작성한 게시물671	70	2023-05-20
    670	홍길동	취미에 대해 작성한 게시물670	30	2023-05-20
    669	박길동	음식에 대해 작성한 게시물669	20	2023-05-20
    668	이길동	날씨에 대해 작성한 게시물668	70	2023-05-20
    667	이길동	날씨에 대해 작성한 게시물667	70	2023-05-20
    666	박길동	음식에 대해 작성한 게시물666	20	2023-05-20
    665	홍길동	취미에 대해 작성한 게시물665	30	2023-05-20
    664	이길동	날씨에 대해 작성한 게시물664	70	2023-05-20
    */
    --> 한 줄 구성
    SELECT NUM, NAME, SUBJECT, HITCOUNT, CREATED FROM(SELECT ROWNUM AS RNUM, DATA.* FROM( SELECT NUM, NAME, SUBJECT, HITCOUNT, TO_CHAR(CREATED,'YYYY-MM-DD') AS CREATED FROM TBL_BOARD ORDER BY NUM DESC ) DATA) WHERE RNUM >= 1 AND RNUM <= 10
    ;
    -------------------------------------------------------------------------------------------------------------------------------------------------
    -- 위의 구문을 테스트하기 위한 PL/SQL 구문 실행 후 확인
    SELECT *
    FROM TBL_BOARD
    ORDER BY NUM;
    
    -- 위의 구문을 테스트하기 위한 특정 게시물 삭제
    DELETE
    FROM TBL_BOARD
    WHERE NUM IN (2,4,5,8,11,12);
    --==>> 6개 행 이(가) 삭제되었습니다.
    
    COMMIT;
    --==>> 커밋 완료.
    -------------------------------------------------------------------------------------------------------------------------------------------------
    
    -- ○ 특정 게시물 조회에 따른 조회수 증가 쿼리문 구성
    --    (게시물 번호 20 인 게시물의 조회수 증가
    UPDATE TBL_BOARD
    SET HITCOUNT = HITCOUNT + 1
    WHERE NUM=20;
    --> 한 줄 구성 
    UPDATE TBL_BOARD SET HITCOUNT = HITCOUNT + 1 WHERE NUM=20
    ;
    --==>> 1 행 이(가) 업데이트되었습니다.
    -------------------------------------------------------------------------------------------------------------------------------------------------
    
    -- ○ 특정 게시물의 내용을 읽어오는 쿼리문 구성
    --    (NUM, NAME, PWD, EMAIL,SUBJECT, CONTENT, IPADDR, HITCOUNT, CREATED)
    SELECT NUM, NAME, PWD, EMAIL,SUBJECT, CONTENT, IPADDR, HITCOUNT, TO_CHAR(CREATED, 'YYYY-MM-DD') AS CREATED
    FROM TBL_BOARD
    WHERE NUM = 20;
    --> 한 줄 구성
    SELECT NUM, NAME, PWD, EMAIL,SUBJECT, CONTENT, IPADDR, HITCOUNT, TO_CHAR(CREATED, 'YYYY-MM-DD') AS CREATED FROM TBL_BOARD WHERE NUM = 20
    ;
    -------------------------------------------------------------------------------------------------------------------------------------------------
    
    -- ○ 특정 게시물 삭제하는 쿼리문 구성
    DELETE
    FROM TBL_BOARD
    WHERE NUM=3;
    --> 한 줄 구성
    DELETE FROM TBL_BOARD WHERE NUM=3
    ;
    --==>> 1 행 이(가) 삭제되었습니다.
    
    -------------------------------------------------------------------------------------------------------------------------------------------------
    
    -- ○ 특정 게시물을 수정하는 쿼리문 구성
    --    (게시물 상세보기 페이지 → Article.jsp 내에서의 처리)
    --     작성자, 패스워드, 이메일, 제목, 내용
    
    UPDATE TBL_BOARD
    SET NAME='요기요', PWD='1234', EMAIL='yogiyo@yogiyo.com', SUBJECT='수정된제목', CONTENT='수정된내용' 
    WHERE NUM = 30;
    --> 한 줄 구성
    UPDATE TBL_BOARD SET NAME='요기요', PWD='1234', EMAIL='yogiyo@yogiyo.com', SUBJECT='수정된제목', CONTENT='수정된내용'  WHERE NUM = 30
    ;
    --==>> 1 행 이(가) 업데이트되었습니다.
    
    COMMIT;
    --==>> 커밋 완료.
    -------------------------------------------------------------------------------------------------------------------------------------------------
     
    -- ○ 특정 게시물(ex.50)의 다음 번호를 얻어오는 쿼리문 구성
    SELECT NVL(MIN(NUM),-1) AS NEXTNUM -- 가장 큰 값 다음 값은 없기 때문에 NULL 처리
    FROM TBL_BOARD
    WHERE NUM>50;
    --> 한 줄 구성
    SELECT NVL(MIN(NUM),-1) AS NEXTNUM FROM TBL_BOARD WHERE NUM>50
    ;
    -------------------------------------------------------------------------------------------------------------------------------------------------
    
    -- ○ 특정 게시물(ex.50)의 이전 번호를 얻어오는 쿼리문 구성
    SELECT NVL(MAX(NUM),-1) AS BEFORENUM -- 가장 작은 값 이전 값은 없기 때문에 NULL 처리
    FROM TBL_BOARD
    WHERE NUM<50;
    --> 한 줄 구성 
    SELECT NVL(MAX(NUM),-1) AS BEFORENUM FROM TBL_BOARD WHERE NUM<50
    ;
    
    -- ==============================================================================================================================================
    -- 검색 조회를 위해 추가++
    
    --○ 검색 대상 데이터 갯수 조회
    SELECT COUNT(*) AS COUNT
    FROM TBL_BOARD
    WHERE SUBJECT LIKE '%세븐틴%';    -- 제목
    --WHERE SUBJECT = '세븐틴';    -- 제목
    
    SELECT COUNT(*) AS COUNT
    FROM TBL_BOARD
    WHERE NAME LIKE '%홍%';    -- 작성자
    --WHERE NAME = '홍길동';    -- 작성자
    
    SELECT COUNT(*) AS COUNT
    FROM TBL_BOARD
    WHERE CONTENT LIKE '%ㄴㅇㄱ%';    -- 내용
    --WHERE CONTENT = 'ㄴㅇㄱ';    -- 내용
    
    --> 한 줄 구성
    SELECT COUNT(*) AS COUNT FROM TBL_BOARD WHERE SUBJECT LIKE '%세븐틴%'
    ;
    SELECT COUNT(*) AS COUNT FROM TBL_BOARD WHERE NAME LIKE '%홍%'
    ;
    SELECT COUNT(*) AS COUNT FROM TBL_BOARD WHERE CONTENT LIKE '%ㄴㅇㄱ%'
    ;
    • WebApp20_scott(plsql).sql
    더보기
    --WebApp20_scott(plsql).sql
    
    SELECT USER
    FROM DUAL;
    --==>> SCOTT
    
    DESC TBL_BOARD;
    --==>>
    /*
    이름       널?       유형             
    -------- -------- -------------- 
    NUM      NOT NULL NUMBER(9)      
    NAME     NOT NULL VARCHAR2(30)   
    PWD      NOT NULL VARCHAR2(20)   
    EMAIL             VARCHAR2(50)   
    SUBJECT  NOT NULL VARCHAR2(100)  
    CONTENT  NOT NULL VARCHAR2(4000) 
    IPADDR            VARCHAR2(20)   
    HITCOUNT NOT NULL NUMBER         
    CREATED  NOT NULL DATE    
    */
    
    
    DECLARE
        V_NUM        NUMBER(9)          := 0;
        V_NAME       VARCHAR2(30);
        V_PWD        VARCHAR2(20);
        V_EMAIL      VARCHAR2(50);
        V_SUBJECT    VARCHAR2(100);
        V_CONTENT    VARCHAR2(4000);
        V_IPADDR     VARCHAR2(20);
        V_HITCOUNT   NUMBER             :=0;
        V_CREATED    DATE              := TO_DATE('2023-05-20','YYYY-MM-DD');
    BEGIN
        LOOP
        
            V_NUM := V_NUM + 1;
            
            IF(MOD(V_NUM,5)=0) THEN
                V_NAME := '홍';
                V_PWD := 'java002$';
                V_EMAIL := 'hong';
                V_SUBJECT := '취미';
                V_CONTENT := '영화감상 관련 내용물 작성';
                V_IPADDR := '211.238.142.50';
                V_HITCOUNT := 30;
            ELSIF(MOD(V_NUM,3)=0) THEN
                V_NAME := '박';
                V_PWD := 'java003$';
                V_EMAIL := 'park';
                V_SUBJECT := '음식';
                V_CONTENT := '김치찌개 관련 내용물 작성';
                V_IPADDR := '211.238.142.54';
                V_HITCOUNT := 20;
            ELSIF(MOD(V_NUM,7)=0) THEN
                V_NAME := '최';
                V_PWD := 'java004$';
                V_EMAIL := 'choi';
                V_SUBJECT := '운동';
                V_CONTENT := '축구 관련 내용물 작성';
                V_IPADDR :='211.238.142.58';
                V_HITCOUNT := 10;
            ELSE
                V_NAME := '이';
                V_PWD := 'java005$';
                V_EMAIL := 'lee';
                V_SUBJECT := '날씨';
                V_CONTENT := '비오는 날 관련 내용물 작성';
                V_IPADDR := '211.238.142.62';
                V_HITCOUNT := 70;
            END IF;
            
            V_NAME := V_NAME || '길동';
            V_SUBJECT := V_SUBJECT ||'에 대해 작성한 게시물' || LTRIM(TO_CHAR(V_NUM));
            V_EMAIL := V_EMAIL || '@test.com';
            
            INSERT INTO TBL_BOARD(NUM, NAME, PWD, EMAIL, SUBJECT, CONTENT, IPADDR, HITCOUNT, CREATED)
            VALUES(V_NUM, V_NAME, V_PWD, V_EMAIL, V_SUBJECT, V_CONTENT, V_IPADDR, V_HITCOUNT, V_CREATED);
            
            EXIT WHEN V_NUM > 672;
            
        END LOOP;
    END;
    --==>> PL/SQL 프로시저가 성공적으로 완료되었습니다.
    • DBConn.java
    더보기
    /*=============================================
    	DBConn.java
    	- 데이터베이스 연결 전용 객체(Singleton)
    	- 예외 처리 : throws
     =============================================*/
    
    package com.util;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    
    public class DBConn
    {
    	private static Connection dbConn;
    	
    	public static Connection getConnection() throws ClassNotFoundException, SQLException
    	{
    		if (dbConn==null)
    		{
    			String url = "jdbc:oracle:thin:@localhost:1521:xe";
    			String user = "scott";
    			String pwd = "tiger";
    			
    			Class.forName("oracle.jdbc.driver.OracleDriver");
    			dbConn = DriverManager.getConnection(url,user,pwd);
    		}
    		return dbConn;
    	}
    	
    	public static Connection getConnection(String url, String user, String pwd) throws ClassNotFoundException, SQLException
    	{
    		if (dbConn==null)
    		{
    			Class.forName("oracle.jdbc.driver.OracleDriver");
    			dbConn = DriverManager.getConnection(url,user,pwd);
    		}
    		return dbConn;
    	}
    	
    	public static void close() throws SQLException
    	{	
    		if (dbConn != null)
    		{
    			if (!dbConn.isClosed())
    				dbConn.close();
    		}
    		
    		dbConn = null;
    	}
    	
    }
    • BoardDTO.java
    더보기
    /*==================
    	BoardDTO.java
    ===================*/
    
    package com.test;
    
    public class BoardDTO
    {
    	// TBL_BOARD 테이블의 레코드 구조와 동일한 속성 구성
    	
    	private int num;      
    	private String name, pwd, email, subject, content, ipAddr, created;
    	private int hitCount;
    	
    	// 사용자 정의 생성자를 정의하지 않음
    	// → default 생성자 자동삽입
    	
    	// getter / setter 구성
    	public int getNum()
    	{
    		return num;
    	}
    	public void setNum(int num)
    	{
    		this.num = num;
    	}
    	public String getName()
    	{
    		return name;
    	}
    	public void setName(String name)
    	{
    		this.name = name;
    	}
    	public String getPwd()
    	{
    		return pwd;
    	}
    	public void setPwd(String pwd)
    	{
    		this.pwd = pwd;
    	}
    	public String getEmail()
    	{
    		return email;
    	}
    	public void setEmail(String email)
    	{
    		this.email = email;
    	}
    	public String getSubject()
    	{
    		return subject;
    	}
    	public void setSubject(String subject)
    	{
    		this.subject = subject;
    	}
    	public String getContent()
    	{
    		return content;
    	}
    	public void setContent(String content)
    	{
    		this.content = content;
    	}
    	public String getIpAddr()
    	{
    		return ipAddr;
    	}
    	public void setIpAddr(String ipAddr)
    	{
    		this.ipAddr = ipAddr;
    	}
    	public String getCreated()
    	{
    		return created;
    	}
    	public void setCreated(String created)
    	{
    		this.created = created;
    	}
    	public int getHitCount()
    	{
    		return hitCount;
    	}
    	public void setHitCount(int hitCount)
    	{
    		this.hitCount = hitCount;
    	}
    	
    	
    }
    • BoardDAO.java
    더보기
    /*==================
    	BoardDAO.java
    ===================*/
    
    package com.test;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    /* -- 내 풀이
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    */
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.ArrayList;
    import java.util.List;
    
    public class BoardDAO
    {
    	// 주요 속성 구성
    	private Connection conn;
    	
    	// 생성자 정의
    	public BoardDAO(Connection conn)
    	{
    		this.conn = conn;
    	}
    	
    	// 게시물 번호의 최대값 얻어내기
    	public int getMaxNum() throws SQLException
    	{
    		int result = 0;
    		/* -- 내 풀이
    		String sql = "SELECT NVL(MAX(NUM),0) AS MAXNUM FROM TBL_BOARD";
    		PreparedStatement pstmt = conn.prepareStatement(sql);
    		
    		ResultSet rs = pstmt.executeQuery();
    		if (rs.next())
    			result = rs.getInt("MAXNUM");
    			
    		rs.close();
    		pstmt.close();
    		*/
    		
    		Statement stmt = null;
    		ResultSet rs = null;
    		String sql = "";
    		
    		try
    		{
    			sql = "SELECT NVL(MAX(NUM),0) AS MAXNUM FROM TBL_BOARD";
    			stmt = conn.createStatement();
    			rs = stmt.executeQuery(sql);
    			if (rs.next())
    				result = rs.getInt("MAXNUM");
    			rs.close();
    			stmt.close();
    			
    		} catch (Exception e)
    		{
    			System.out.println(e.toString());
    		}
    		
    		return result;
    	}
    	
    	// 게시물 작성 → 데이터 입력
    	public int insertData(BoardDTO dto)
    	{
    		int result = 0;
    		PreparedStatement pstmt = null;
    		String sql = "";
    		
    		try
    		{	
    			// hitCount 기본값 『0』 또는 『default』 또는 『입력항목생략』 가능
    			// created 기본값 『sysdate』 또는 『default』 또는 『입력항목생략』 가능
    			sql = "INSERT INTO TBL_BOARD(NUM,NAME,PWD,EMAIL,SUBJECT, CONTENT, IPADDR, HITCOUNT, CREATED)"
    				+ " VALUES(?,?,?,?,?,?,?,0,SYSDATE)";
    		
    			pstmt = conn.prepareStatement(sql);
    			
    			pstmt.setInt(1, dto.getNum());
    			pstmt.setString(2, dto.getName());
    			pstmt.setString(3, dto.getPwd());
    			pstmt.setString(4, dto.getEmail());
    			pstmt.setString(5, dto.getSubject());
    			pstmt.setString(6, dto.getContent());
    			pstmt.setString(7, dto.getIpAddr());
    			
    			result = pstmt.executeUpdate();
    			
    			pstmt.close();
    			
    		} catch (Exception e)
    		{
    			System.out.println(e.toString());
    		}
    		return result;
    	}// end insertData(BoardDTO dto)
    	
    	// DB 레코드의 갯수를 가져오는 메소드 정의 (지금은 전체 갯수 조회)
    	// → 추후 검색 기능을 작업하게 되면 수정하게 될 메소드 (검색 대상 갯수 조회)
    	/*
    	public int getDataCount()
    	{
    		int result = 0;
    
    		Statement stmt = null;
    		ResultSet rs = null;
    		String sql = "";
    		
    		try
    		{
    			stmt = conn.createStatement();
    			sql = "SELECT COUNT(*) AS COUNT FROM TBL_BOARD";
    			
    			rs = stmt.executeQuery(sql);
    			if (rs.next())
    				result = rs.getInt(1);
    			
    			rs.close();
    			stmt.close();
    			
    		} catch (Exception e)
    		{
    			System.out.println(e.toString());
    		}
    		
    		return result;
    	}// end getDataCount()
    	*/
    	// 검색 기능 추가하며 -- 메소드 내용 변경
    	public int getDataCount(String searchKey, String searchValue)
    	{
    		int result = 0;
    		
    		PreparedStatement pstmt = null;
    		ResultSet rs = null;
    		String sql = "";
    		
    		try
    		{
    			// check : 해당 내용을 포함하는 값을 검색하기 위해서
    			searchValue = "%" + searchValue + "%";
    			
    			sql = "SELECT COUNT(*) AS COUNT"
    					+ " FROM TBL_BOARD"
    					+ " WHERE " + searchKey + " LIKE ?";
    			
    			pstmt = conn.prepareStatement(sql);
    			pstmt.setString(1, searchValue);
    			
    			rs = pstmt.executeQuery();
    			if (rs.next())
    				result = rs.getInt("COUNT");
    			rs.close();
    			pstmt.close();
    			
    		} catch (Exception e)
    		{
    			System.out.println(e.toString());
    		}
    		
    		return result;
    	}
    	
    	// 특정 영역의(시작번호 ~ 끝번호)게시물의 목록을
    	// 읽어오는 메소드 정의
    	// → 추후 검색 기능을 작업하게 되면 수정하게 될 메소드 (검색 대상 리스트 조회)
    	/*
    	public List<BoardDTO> getLists(int start, int end)
    	{
    		List<BoardDTO> result = new ArrayList<BoardDTO>();
    		
    		PreparedStatement pstmt = null;
    		ResultSet rs = null;
    		String sql = "";
    		
    		try
    		{
    			// 띄어쓰기 조심!
    			sql += "SELECT NUM, NAME, SUBJECT, HITCOUNT, CREATED";
    			sql += " FROM";
    			sql += "(";
    			sql += "    SELECT ROWNUM AS RNUM, DATA.*";
    			sql += "     FROM";
    			sql += "    (";
    			sql += "        SELECT NUM, NAME, SUBJECT, HITCOUNT, TO_CHAR(CREATED,'YYYY-MM-DD') AS CREATED";
    			sql += "         FROM TBL_BOARD";
    			sql += "         ORDER BY NUM DESC";
    			sql += "    ) DATA";
    			sql += ")";
    			sql += " WHERE RNUM >= ? AND RNUM <= ?";
    			
    			//sql="SELECT NUM, NAME, SUBJECT, HITCOUNT, CREATED "
    			//	+ " FROM(SELECT ROWNUM AS RNUM, DATA.* FROM"
    			//	+ " ( SELECT NUM, NAME, SUBJECT, HITCOUNT, TO_CHAR(CREATED,'YYYY-MM-DD') AS CREATED"
    			//	+ " FROM TBL_BOARD ORDER BY NUM DESC ) DATA)"
    			//	+ " WHERE RNUM >= ? AND RNUM <= ?";
    			
    			
    			pstmt = conn.prepareStatement(sql);
    			
    			pstmt.setInt(1, start);
    			pstmt.setInt(2, end);
    			
    			rs = pstmt.executeQuery();
    			while (rs.next())
    			{
    				BoardDTO dto = new BoardDTO();
    				dto.setNum(rs.getInt("NUM"));
    				dto.setName(rs.getString("NAME"));
    				dto.setSubject(rs.getString("SUBJECT"));
    				dto.setHitCount(rs.getInt("HITCOUNT"));
    				dto.setCreated(rs.getString("CREATED"));
    				
    				result.add(dto);
    			}
    			
    			rs.close();
    			pstmt.close();
    			
    		} catch (Exception e)
    		{
    			System.out.println(e.toString());
    		}
    		
    		return result;
    	}// end getLists(int start, int end)
    	*/
    	// check
    	// 검색 기능을 추가하며 -- 메소드 내용 변경
    	public List<BoardDTO> getLists(int start, int end, String searchKey, String searchValue)
    	{
    		List<BoardDTO> result = new ArrayList<BoardDTO>();
    		
    		PreparedStatement pstmt = null;
    		ResultSet rs = null;
    		String sql = "";
    		
    		try
    		{
    			// check
    			searchValue = "%" + searchValue + "%";
    			
    			// 띄어쓰기 조심!
    			sql += "SELECT NUM, NAME, SUBJECT, HITCOUNT, CREATED";
    			sql += " FROM";
    			sql += "(";
    			sql += "    SELECT ROWNUM AS RNUM, DATA.*";
    			sql += "     FROM";
    			sql += "    (";
    			sql += "        SELECT NUM, NAME, SUBJECT, HITCOUNT, TO_CHAR(CREATED,'YYYY-MM-DD') AS CREATED";
    			sql += "         FROM TBL_BOARD";
    			sql += "         WHERE " + searchKey + " LIKE ?";
    			sql += "         ORDER BY NUM DESC";
    			sql += "    ) DATA";
    			sql += ")";
    			sql += " WHERE RNUM >= ? AND RNUM <= ?";
    			
    			pstmt = conn.prepareStatement(sql);
    			
    			pstmt.setString(1, searchValue); 	// 추가 구문(검색 키워드)
    			pstmt.setInt(2, start);				// 인덱스 변경
    			pstmt.setInt(3, end);				// 인덱스 변경
    			
    			rs = pstmt.executeQuery();
    			while (rs.next())
    			{
    				BoardDTO dto = new BoardDTO();
    				dto.setNum(rs.getInt("NUM"));
    				dto.setName(rs.getString("NAME"));
    				dto.setSubject(rs.getString("SUBJECT"));
    				dto.setHitCount(rs.getInt("HITCOUNT"));
    				dto.setCreated(rs.getString("CREATED"));
    				
    				result.add(dto);
    			}
    			
    			rs.close();
    			pstmt.close();
    			
    		} catch (Exception e)
    		{
    			System.out.println(e.toString());
    		}
    		
    		return result;
    	}// end getLists(int start, int end)
    	
    	
    	// 특정 게시물 조회에 따른 조회수 증가 메소드 정의
    	public int updateHitCount(int num)
    	{
    		int result = 0;
    		
    		PreparedStatement pstmt = null;
    		String sql = "";
    		
    		try
    		{
    			sql = "UPDATE TBL_BOARD SET HITCOUNT = HITCOUNT + 1 WHERE NUM=?";
    			pstmt = conn.prepareStatement(sql);
    			pstmt.setInt(1, num);
    			
    			result = pstmt.executeUpdate();
    			
    			pstmt.close();
    			
    		} catch (Exception e)
    		{
    			System.out.println(e.toString());
    		}
    		
    		return result;
    	} // end updateHitCount(int num)
    	
    	// 특정 게시물의 내용을 읽어오는 메소드 정의
    	public BoardDTO getReadData(int num)
    	{
    		BoardDTO result = null;
    		PreparedStatement pstmt = null;
    		String sql = "";
    		
    		try
    		{
    			sql = "SELECT NUM, NAME, PWD, EMAIL,SUBJECT, CONTENT"
    					+ ", IPADDR, HITCOUNT, TO_CHAR(CREATED, 'YYYY-MM-DD') AS CREATED"
    					+ " FROM TBL_BOARD WHERE NUM = ?";
    			pstmt = conn.prepareStatement(sql);
    			
    			pstmt.setInt(1, num);
    			ResultSet rs = pstmt.executeQuery();
    			
    			if (rs.next())
    			{
    				result = new BoardDTO();
    				
    				result.setNum(rs.getInt("NUM"));
    				result.setName(rs.getString("NAME"));
    				result.setPwd(rs.getString("PWD"));
    				result.setEmail(rs.getString("EMAIL"));
    				result.setSubject(rs.getString("SUBJECT"));
    				result.setContent(rs.getString("CONTENT"));
    				result.setIpAddr(rs.getString("IPADDR"));
    				result.setHitCount(rs.getInt("HITCOUNT"));
    				result.setCreated(rs.getString("CREATED"));
    			}
    			
    			rs.close();
    			pstmt.close();
    					
    		} catch (Exception e)
    		{
    			System.out.println(e.toString());
    		}
    		
    		return result;
    	}// end getReadData(int num)
    	
    	// 특정 게시물을 삭제하는 기능의 메소드
    	public int deleteData(int num)
    	{
    		int result = 0;
    		PreparedStatement pstmt = null;
    		String sql = "";
    		
    		try
    		{
    			sql = "DELETE FROM TBL_BOARD WHERE NUM=?";
    			pstmt = conn.prepareStatement(sql);
    			
    			pstmt.setInt(1, num);
    			result = pstmt.executeUpdate();
    			
    			pstmt.close();
    		} catch (Exception e)
    		{
    			System.out.println(e.toString());
    		}
    		
    		return result;
    	}// end deleteData(int num)
    	
    	// 특정 게시물을 수정하는 쿼리문 구성
    	public int updateData(BoardDTO dto)
    	{
    		int result = 0;
    		
    		PreparedStatement pstmt = null;
    		String sql = "";
    		
    		try
    		{
    			sql = "UPDATE TBL_BOARD"
    					+ " SET NAME=?, PWD=?, EMAIL=?, SUBJECT=?, CONTENT=?"
    					+ "  WHERE NUM =?";
    			pstmt = conn.prepareStatement(sql);
    			
    			pstmt.setString(1, dto.getName());
    			pstmt.setString(2, dto.getPwd());
    			pstmt.setString(3, dto.getEmail());
    			pstmt.setString(4, dto.getSubject());
    			pstmt.setString(5, dto.getContent());
    			pstmt.setInt(6, dto.getNum());
    			
    			result = pstmt.executeUpdate();
    			
    			pstmt.close();
    		
    		} catch (Exception e)
    		{
    			System.out.println(e.toString());
    		}
    		
    		return result;
    		
    	}// end updateData(BoardDTO dto)
    	
    	// 특정 게시물의 이전 번호를 얻어오는 쿼리문 구성
    	// → 이전 게시물이 존재하지 않을 경우 -1 반환
    	public int getBeforeNum(int num)
    	{
    		int result = 0;
    		
    		PreparedStatement pstmt = null;
    		String sql = "";
    		
    		try
    		{
    			sql = "SELECT NVL(MAX(NUM),-1) AS NEXTNUM FROM TBL_BOARD WHERE NUM<?";
    			pstmt = conn.prepareStatement(sql);
    			
    			pstmt.setInt(1, num);
    			ResultSet rs = pstmt.executeQuery();
    			if (rs.next())
    				result = rs.getInt(1);
    			rs.close();
    			pstmt.close();
    			
    		} catch (Exception e)
    		{
    			System.out.println(e.toString());
    		}
    		
    		return result;
    	}// end getBeforeNum(int num)
    	
    	
    	// 특정 게시물의 다음 번호를 얻어오는 쿼리문 구성
    	// → 다음 게시물이 존재하지 않을 경우 -1 반환
    	public int getNextNum(int num)
    	{
    		int result = 0;
    		
    		PreparedStatement pstmt = null;
    		String sql = "";
    		
    		try
    		{
    			sql = "SELECT NVL(MIN(NUM),-1) AS BEFORENUM FROM TBL_BOARD WHERE NUM>?";
    			pstmt = conn.prepareStatement(sql);
    			
    			pstmt.setInt(1, num);
    			ResultSet rs = pstmt.executeQuery();
    			if (rs.next())
    				result = rs.getInt(1);
    			rs.close();
    			pstmt.close();
    			
    		} catch (Exception e)
    		{
    			System.out.println(e.toString());
    		}
    		
    		return result;
    	}// end getNextNum(int num)
    	
    }
    • MyUtil.java
    더보기
    /*=========================
    	MyUtil.java
    	- 게시판 페이징 처리 
    ==========================*/
    
    // check
    // 이번에 같이 확인해보고자 하는 페이징 처리 기법은
    // 다양한 방법들 중에 한가지(그나마 쉬운 것을 골라...)이다
    // 학습을 마친 이후에... 꼭 추가적으로 개념을 정리하고
    // 확장 시키고, 다른 방법들도 찾아보고 공부할 수 있도록 하자
    
    package com.util;
    
    public class MyUtil
    {
    	// ■ 전체 페이지 수를 구하는 메소드
    	// numPerPage : 한 페이지에 표시할 데이터(게시물)의 수
    	// dataCount : 전체 데이터(게시물) 수
    	public int getPageCount(int numPerPage, int dataCount)
    	{
    		int pageCount = 0;
    		
    		pageCount = dataCount / numPerPage;
    		if (dataCount%numPerPage!=0)
    			pageCount++;
    		
    		return pageCount;
    	}
    	//-- 한 페이지에 10개의 게시물을 출력할 때
    	//   총 32개의 게시물을 페이지로 구성하기 위해서는
    	//   『32 / 10』의 연산을 수행하여 결과 3을 얻을 수 있다.
    	//   → 『pageCount = dataCount / numPerPage;』
    	//   그런데 이 때, 나머지 2개의 게시물을 출력해주기 위해서는
    	//   페이지 하나가 더 필요하다.
    	//   → 『pageCount++;』
    	
    	//=============================================================================================================
    	
    	// ■ 페이징 처리 기능의 메소드
    	// currentPage : 현재 표시할 페이지
    	// totalPage : 전체 페이지 수
    	// listUrl : 링크를 설정할 url 
    	public String pageIndexList(int currentPage, int totalPage, String listUrl)
    	{
    		// 실제 페이징을 저장할 StringBuffer 변수
    		StringBuffer strList = new StringBuffer();
    		
    		int numPerBlock = 10;
    		//-- 페이징 처리 시 게시물 리스트 하단의 숫자를 10개씩 보여주겠다.
    		
    		int currentPageSetup;
    		//-- 현재 페이지(를 셋팅하는 변수)(이 페이지를 기준으로 보여주는 숫자가 달라져야하기 때문)//아래 추가 설명 확인
    		
    		int page;
    		//-- 하단에 나타날 페이지 1 2 3 ... 8 9 10 과 같이 보여줄 변수
    		
    		int n;
    		//-- 이전 페이지 블럭과 같은 처리에서 이동하기 위한 변수
    		//   (얼마만큼 이동해야 하는지)
    		
    		// 페이징 처리가 별도로 필요하지 않은 경우
    		//-- 데이터가 즉, 게시물이 존재하지 않아 페이징 처리를 할 필요가 없는 경우
    		if (currentPage==0)
    			return ""; 	// 빈 문자열 반환하고 메소드 종료
    		
    		// ※ 페이지 요청을 처리하는 과정에서
    		//    URL 경로의 패턴에 대한 처리
    
    		/*
    			- 클라이언트 요청의 형태 → List.jsp → (가공) → List.jsp + 『?』 + pageNum=1
    			  → 『List.jsp?pageNum=1』 와 같은 형태
    			- 클라이언트 요청의 형태 → List.jsp?searchKey=title → (가공) → List.jsp?searchKey=title + 『&』 + pageNum=1
    			  → 『List.jsp?searchKey=title&pageNum=1』 와 같은 형태 
    				 └ 이와 같이 작성해야 목록으로 돌아올 때 내가 게시물을 들어갔다가 목록으로 나올 때
    				 	해당 목록 페이지를 유지하면서 나올 수 있음
    			   		▶ 15페이지 게시물 보고 -> 목록으로 -> 15페이지에 머물러야 함! 
    		 */
    		
    		
    		// ◈ 링크를 설정할 URL 에 대한 사전 가공 처리
    		if (listUrl.indexOf("?") != -1)	// 링크를 설정할 URL 에 『?』 가 들어있으면...
    		{
    			listUrl = listUrl + "&";	// listUrl += "&";
    		}
    		else							// 링크를 설정할 URL 에 『?』 가 없으면...
    		{
    			listUrl = listUrl + "?";	// listUrl += "?";
    		}
    		//-- 예를 들어, 검색 값이 존재하면...
    		//   이미 request 에 searchKey 와 searchValue 가 들어있는 상황이므로
    		//   『&』 를 붙여서 속성을 추가해 주어야한다.
    		
    		// ◈ currentPagdSetup = 표시할 리스트 페이지 중 첫 페이지 -1
    		currentPageSetup = (currentPage / numPerBlock) * numPerBlock;
    		//-- 만약 현재 페이지가 5페이지 이고(currentPage=5)
    		//   리스트 하단에 보여줄 페이지 갯수가 10 이면(numPerBlock=10)
    		//   『5/10=0』 이며... 여기에 『*10』 (10을 곱해도) 0 이다.
    		//   하지만, 현재 페이지가 11페이지라면(currentPage=11)
    		//   『11/10=1』이며... 여기에 『*10』 (10을 곱하면) 10 이다.
    		//   그러면.. currentPageSetup 은 10이 되는 것이다.
    		/*
    		┌ 여기가 currentPageSetup
    		20	 21 22 23 ... 29 30
    		10	 11 12 13 ... 19 20
    		 0	  1  2  3 ...  9 10
    		 */
    
    		if (currentPage % numPerBlock == 0)
    		{
    			currentPageSetup = currentPageSetup - numPerBlock;
    		}
    		//-- 만약 위 처리에서 (라인89)
    		//   현재 페이지가 10 단위라면 (예를 들어 20)
    		//   『20/10=2』 이며 여기에 『*10』 (10을 곱해서) 20이 되는데,
    		//    이와 같은 상황이라면 다시 10을 빼서 10으로 만들어주기 위한 구분이 필요
    		
    		
    		// ◈ 1 페이지(맨처음으로)
    		// currentPageSetup 이 0 이면 1 2 ... 9 10 이기 때문에 필요X
    		// currentPageSetup > 0 을 세팅한 이유는 
    		// AJAX 로 실시간으로 처리할 때(시점이 다른 상황을 고려)게시물 수가 엄청 줄어들거나 하면 확인할 필요가 있는데
    		// 현재는 파라미터로 totalPage를 넘겨받고 있기 때문에 생략 가능한 조건이다.
    		if ((totalPage>numPerBlock) && (currentPageSetup>0))
    		{
    			strList.append(" <a href='"+ listUrl +"pageNum=1'>1</a>");
    		}
    		//-- listUrl 은 위에서 (라인 75~83) 이미 전처리가 끝난 상황이기 때문에
    		//   『...?』 상태 또는 『...?...&』인 상태이다.
    		//    이로 인해 결과는
    		//   『..?pageNum=1』 이거나 『..?...&pageNum=1』 이 되는 상황이다.
    		
    		
    		// ◈ Prev 페이지(이전 페이지로)
    		n = currentPage - numPerBlock;
    		//-- n : 해당 페이지만큼 앞으로 가기 위한 변수
    		
    		if ( (totalPage>numPerBlock) && (currentPageSetup>0))
    		{
    			strList.append(" <a href='"+ listUrl +"pageNum=" + n + "'>Prev</a>");
    		}
    		//-- currentPageSetup 이 0 보다 큰 경우는
    		//   이미 페이지가 11페이지 이상이라는 의미
    		//   이 때, 현재 페이지(currentPage)가 11 이상일 경우
    		//   『Prev』를 붙이기 위한 구문
    		//-- 『Prev』를 클릭할 경우,
    		//    n 변수 페이지로 이동하는데
    		//    12 에서 『Prev』할 경우 2 페이지가 되고,
    		//    22 에서 『Prev』할 경우 12 페이지가 될 수 있도록 처리하는 방식이다.
    		
    		
    		// ◈ 각 페이지 바로가기
    		page = currentPageSetup + 1 ; 
    		//-- 『+1』을 수행하는 이유는
    		//    앞에서 currentPageSetup 에서 10을 가져왔다면
    		//    10 부터 시작하는 것이 아니라
    		//    바로가기 페이지는 11 부터 시작해야 하기 때문이다.
    		
    		while ((page<=totalPage) && (page<=currentPageSetup+numPerBlock))
    		{
    			if (page == currentPage)
    			{
    				// 현재 있는 페이지라 링크 이동X 색상으로 표시
    				strList.append(" <span style='color:orange; font-weight:bold;'>"+page+"</span>");
    			}
    			else
    			{
    				strList.append(" <a href='"+ listUrl + "pageNum=" + page +"'>" + page + "</a>");
    			}
    			
    			page++;
    			
    		}
    		
    		
    		// ◈ Next 페이지(다음페이지로) -- 『Prev』페이지 설명 참조
    		n = currentPage + numPerBlock;
    		if ((totalPage-currentPageSetup) > numPerBlock)
    		{
    			strList.append(" <a href='"+listUrl+"pageNum="+n+"'>Next</a>");
    		}
    
    		
    		// ◈ 마지막 페이지(마지막으로)
    		//-- 유동적으로 늘어남
    		if ((totalPage>numPerBlock) && (currentPageSetup+numPerBlock)<totalPage)
    		{
    			strList.append(" <a href='"+listUrl+"pageNum="+totalPage+"'>"+totalPage+"</a>");
    		}
    		
    		// 최종 페이징 처리된 내용 반환
    		return strList.toString();
    		
    	}// end pageIndexList(int currentPage, int totalPage, String listUrl)
    		
    	
    }// end Class MyUtil
    • List.jsp
    더보기
    <%@page import="com.test.BoardDTO"%>
    <%@page import="java.util.List"%>
    <%@page import="com.util.MyUtil"%>
    <%@page import="java.sql.Connection"%>
    <%@page import="com.util.DBConn"%>
    <%@page import="com.test.BoardDAO"%>
    <%@page import="java.net.URLDecoder"%>
    <%@ page contentType="text/html; charset=UTF-8"%>
    <%
    	request.setCharacterEncoding("UTF-8");
    	String cp = request.getContextPath();
    %>
    <%
    	// 이전 페이지(?)로부터 넘어온 게시물 번호 수신
    	// 명확하게 지정해둘 수 없음 - 자기자신일 수도 다른 페이지일수도,,,
    	String strNum = request.getParameter("num");
    	int num = 0;
    	if (strNum != null)
    		num = Integer.parseInt(strNum);
    	
    	// 이전 페이지(?)로부터 넘어온 페이지 번호 수신
    	String pageNum = request.getParameter("pageNum");
    	int currentPage = 1;
    	if (pageNum != null)
    		currentPage = Integer.parseInt(pageNum);
    	
    	// 이전 페이지(?)로부터 검색 키와 검색 값 수신
    	String searchKey = request.getParameter("searchKey");
    	String searchValue = request.getParameter("searchValue");
    	
    	if (searchKey != null)	//-- 검색 기능을 통해 이 페이지(List.jsp)가 요청되었을 경우
    	{
    		// 넘어온 값이 GET 방식이라면...
    		// → GET 은 한글 문자열을 인코딩해서 보내기 때문에
    		//    → 디코딩 처리가 필요
    		//if (request.getMethod()) 			// request.getMethod() - get방식인지 post 방식인지 알 수 있음 
    		/*
    			<form method="get"></form>  -->   "get"
    			<form method="GET"></form>  -->   "GET"
    			이렇게 처리되기 때문에...
    		*/
    		if (request.getMethod().equalsIgnoreCase("GET")) // 대소문자 구분하지않게 하기 위함
    		{
    			// 디코딩 처리
    			searchValue = URLDecoder.decode(searchValue, "UTF-8");	// 디코딩 -> 문자열반환 -> 해당 값을 다시 Value에 담기			
    		}
    			
    	}
    	else					//-- 검색기능을 활용하지 않고 기본적인 페이지 요청이 이루어졌을 경우
    	{
    		// 검색한 결과에 대한 인지를 시켜주기 위해서 검색 했을 때, 
    		// [내용 ▼][날씨] 와 같이 검색하면 -> 이 부분이 남아있어야 검색을 한 결과라고 확인할 수 있어야하기 때문에
    		// 검색하지 않았다면 초기상태와 같이 보이게 하기 위해서
    		searchKey = "subject";
    		searchValue = "";
    	}
    	
    	Connection conn = DBConn.getConnection();
    	BoardDAO dao = new BoardDAO(conn);
    	MyUtil myUtil = new MyUtil();
    	
    	// 전체 데이터 갯수 구하기
    	//int dataCount = dao.getDataCount();	//-- 검색기능 추가 이전 코드
    	int dataCount = dao.getDataCount(searchKey, searchValue);			// check! 
    	
    	// 전체 페이지를 기준으로 총 페이지 수 계산
    	int numPerPage = 10;		//-- 한 페이지에 표시할 데이터 갯수
    	int totalPage = myUtil.getPageCount(numPerPage, dataCount);
    	
    	// 전체 페이지 수 보다 표시할 페이지가 큰 경우
    	// 표시할 페이지를 전체 페이지로 처리
    	// → 데이터를 삭제해서 페이지가 줄어들었을 경우...
    	if (currentPage > totalPage)
    		currentPage = totalPage;
    	
    	// 데이터베이스에서 가져올 시작과 끝 위치
    	int start = (currentPage-1)*numPerPage+1;
    	int end = currentPage * numPerPage;
    	
    	// 실제 리스트 가져오기
    	//List<BoardDTO> lists = dao.getLists(start, end);	//-- 검색기능 추가 이전 코드
    	List<BoardDTO> lists = dao.getLists(start, end, searchKey, searchValue);	// check
    	
    	// 페이징 처리
    	String param = "";
    	
    	// 검색값이 존재한다면
    	if (!searchValue.equals(""))
    	{
    		param += "?searchKey=" + searchKey;
    		param += "&searchValue=" + searchValue;
    	}
    
    	String listUrl = "List.jsp" + param;
    	String pageIndexList = myUtil.pageIndexList(currentPage, totalPage, listUrl);
    	
    	// 글 내용 보기 주소
    	String articleUrl = cp + "/Article.jsp";
    	
    	if(param.equals(""))
    	{
    		articleUrl = articleUrl + "?pageNum=" + currentPage;
    	}
    	else
    	{
    		articleUrl = articleUrl + param + "&pageNum=" + currentPage;
    	}
    	
    	DBConn.close();
    	
    %>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>List.jsp</title>
    <link rel="stylesheet" type="text/css" href="<%=cp %>/css/style.css">
    <link rel="stylesheet" type="text/css" href="<%=cp %>/css/list.css">
    <script type="text/javascript">
    	function sendIt()
    	{
    		var f = document.searchForm;
    		
    		// 검색 키워드에 대한 유효성 검사 코드 삽입 및 활용 가능
    		
    		f.action = "<%=cp %>/List.jsp?pageNum=1";
    		
    		f.submit();
    	}
    </script>
    </head>
    <body>
    
    <!-- 관찰 -->
    <%-- <div>
    	<h1><%=cp %></h1>
    </div>
    --%>
    
    <div id="bbsList">
    
    	<div id="bbsList_title">
    		<a href="<%=cp %>/List.jsp">게 시 판 (JDBC 연동 버전)</a>
    	</div>
    
    	<div id="bbsList_header">
    	
    		<div id="leftHeader">
    			
    			<!-- 검색 폼 구성 -->
    			<form action="" name="searchForm" method="post">
    				<select name="searchKey" class="selectField">
    				<!-- 정적구성 선택 옵션을 분기 -->
    				<!-- 
    					<option value="subject">제목</option>
    					<option value="name">작성자</option>
    					<option value="content">내용</option>
    				-->
    				
    				<% if (searchKey.equals("name")){ %> 			<!-- 수신한 searchKey 가 name 이라면... --> 
    				<option value="subject">제목</option>
    				<option value="name" selected="selected">작성자</option>
    				<option value="content">내용</option>
    				<% } else if(searchKey.equals("content")){	%>	<!-- 수신한 searchKey 가 content 라면... -->
    					<option value="subject">제목</option>
    					<option value="name">작성자</option>
    					<option value="content" selected="selected">내용</option>				
    				<% } else {%>									<!-- 수신한 searchKey 가 subject 이거나... 없으면 -->
    					<option value="subject">제목</option>
    					<option value="name">작성자</option>
    					<option value="content">내용</option>				
    				<% } %>
    				</select>
    				
    				<input type="text" name="searchValue" class="textField" value="<%=searchValue %>">
    				<input type="button" value="검색" class="btn2" onclick="sendIt()">	<!-- onclick check -->
    			</form>
    		
    		</div><!-- #leftHeader -->
    	
    		<div id="rightHeader">
    			<input type="button" value="글올리기" class="btn2"
    			 onclick="javascript:location.href='<%=cp %>/Created.jsp'">
    		</div><!-- #rightHeader -->		
    	
    	</div><!-- #bbsList_header -->
    	
    	<div id="bbsList_list">
    	
    		<div id="title">
    			<dl>
    				<dt class="num">번호</dt>
    				<dt class="subject">제목</dt>
    				<dt class="name">작성자</dt>
    				<dt class="created">작성일</dt>
    				<dt class="hitCount">조회수</dt>
    			</dl>
    		</div><!-- #title -->
    	
    		<div id="lists">
    			<!-- 
    			<dl>
    				<dd class="num">1</dd>
    				<dd class="subject"><a href="">안녕하세요</a></dd>
    				<dd class="name">이팔즈</dd>
    				<dd class="created">2023-05-31</dd>
    				<dd class="hitCount">20</dd>
    			</dl>
    			-->
    			
    			<%
    			for (BoardDTO dto : lists)
    			{
    			%>
    			<dl>
    				<dd class="num"><%=dto.getNum() %></dd>
    				<dd class="subject">
    					<a href="<%=articleUrl %>&num=<%=dto.getNum() %>"><%=dto.getSubject() %></a>
    				</dd>
    				<dd class="name"><%=dto.getName() %></dd>
    				<dd class="created"><%=dto.getCreated() %></dd>
    				<dd class="hitCount"><%=dto.getHitCount() %></dd>
    			</dl>
    			<%
    			}
    			%>
    			
    		</div><!-- #lists -->
    	
    		<div id="footer">
    			<!-- <p>1 Prev 21 22 23 24 25 26 27 28 29 30 Next 52</p> -->
    			<!-- <p>등록된 게시물이 존재하지 않습니다.</p> -->
    			
    			<p>
    			<%
    			if(dataCount!=0)
    			{
    			%>
    				<%=pageIndexList %>
    			<%	
    			}
    			else
    			{
    			%>
    				등록된 게시물이 존재하지 않습니다.
    			<%
    			}
    			%>
    			</p>
    			
    		</div><!-- #footer -->
    	
    	</div><!-- #bbsList_list -->
    	
    </div><!-- #bbsList -->
    
    </body>
    </html>
    • Created.jsp
    더보기
    <%@ page contentType="text/html; charset=UTF-8"%>
    <%
    	request.setCharacterEncoding("UTF-8");
    	String cp = request.getContextPath();
    %>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Created.jsp</title>
    <link rel="stylesheet" type="text/css" href="<%=cp %>/css/style.css">
    <link rel="stylesheet" type="text/css" href="<%=cp %>/css/created.css">
    <script type="text/javascript" src="<%=cp %>/js/util.js"></script>
    <script type="text/javascript">
    	function sendIt()
    	{
    		f = document.myForm;
    		
    		// 제목 입력 확인 -------------------------------------
    		// 필수 입력 항목 기재 여부 확인 및 공백 처리
    		
    		str = f.subject.value;
    		str = str.trim();
    		
    		// 테스트
    		//alert("|" + str + "|");
    		
    		if (!str)
    		{
    			alert("\n제목을 입력하세요~!!!");
    			f.subject.focus();
    			return;
    		}
    		// ------------------------------------- 제목 입력 확인
    
    		// 이름 입력 확인 -------------------------------------
    		// 필수 입력 항목 기재 여부 확인 및 공백 처리
    		str = f.name.value;
    		str = str.trim();
    		
    		if (!str)
    		{
    			alert("\n작성자 이름을 입력하세요~!!!");
    			f.name.focus();
    			return;
    		}
    		// ------------------------------------- 이름 입력 확인
    
    		// 이메일 검사 ----------------------------------------
    		// 필수 입력 항목이 아니므로 선택적인 입력이 가능하지만
    		// 입력을 한 상황이라면,
    		// 이메일 형식에 맞게 입력했는지 확인하는 처리
    		if (f.email.value)	// 이메일 항목에 내용을 입력한 상황이라면...
    		{
    			if (!isValidEmail(f.email.value))	// 유효한 형태가 아니라면!
    			{
    				alert("\n정상적인 이메일 형식을 입력하세요!");
    				f.email.focus();
    				return;
    			}			
    		}
    		// ---------------------------------------- 이메일 검사
    		
    		// 내용 입력 확인 -------------------------------------
    		// 필수 입력 항목 기재 여부 확인 및 공백 처리
    		str = f.content.value;
    		str = str.trim();
    		
    		if (!str)
    		{
    			alert("\n내용을 입력하세요");
    			f.content.focus();
    			return;
    		}
    		// ------------------------------------- 내용 입력 확인
    	
    		// 패스워드 입력 확인 ---------------------------------
    		// 필수 입력 항목 기재 여부 확인 및 공백 처리
    		str = f.pwd.value;
    		str = str.trim();
    		
    		if (!str)
    		{
    			alert("\n패스워드를 입력하세요!");
    			f.pwd.focus();
    			return;
    		}
    		
    		// --------------------------------- 패스워드 입력 확인
    		
    		// 테스트 
    		//alert("체크 완료!");
    		
    		// 폼의 액션 속성 채워넣기
    		f.action = "<%=cp %>/Created_ok.jsp";
    		
    		f.submit();
    	}
    </script>
    </head>
    <body>
    
    <div id="bbs">
    	
    	<div id="bbs_title">
    		게 시 판 (JDBC 연동 버전)
    	</div>
    	
    	<!-- <form action="Created_ok.jsp" method="post" name="myForm"> --> <!-- action 값 지정시 -->
    	<form action="" method="post" name="myForm">
    		<div id="bbsCreated">
    			
    			<div class="bbsCreated_bottomLine">
    				<dl>
    					<dt>제&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;목</dt>
    					<dd>
    						<input type="text" name="subject" size="64" maxlength="100" class="boxTF">
    					</dd>
    				</dl>
    			</div><!-- .bbsCreated_bottmLine -->
    		
    			<div class="bbsCreated_bottomLine">
    				<dl>
    					<dt>작 성 자</dt>
    					<dd>
    						<input type="text" name="name" size="35" maxlength="20" class="boxTF">
    					</dd>
    				</dl>
    			</div><!-- .bbsCreated_bottmLine -->
    		
    			<div class="bbsCreated_bottomLine">
    				<dl>
    					<dt>이 메 일</dt>
    					<dd>
    						<input type="email" name="email" size="35" maxlength="50" class="boxTF">
    					</dd>
    				</dl>
    			</div><!-- .bbsCreated_bottmLine -->
    
    			<div id="bbsCreated_content">
    				<dl>
    					<dt>내&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;용</dt>
    					<dd>
    						<textarea rows="12" cols="63" name="content" class="boxTA"></textarea>
    					</dd>
    				</dl>
    			</div><!-- #bbsCreated_content -->
    			
    			<div class="bbsCreated_noLine">
    				<dl>
    					<dt>패스워드</dt>
    					<dd>
    						<input type="password" name="pwd" size="35" maxlength="10" class="boxTF">
    						<span style="font-size: 6pt;">(게시물 수정 및 삭제 시 필요)</span>
    					</dd>
    				</dl>
    			</div><!-- .bbsCreated_noLine -->			
    		
    			<div id="bbsCreated_footer">
    				<input type="button" value="등록하기" class="btn2" onclick="sendIt()">
    				<input type="reset" value="다시입력" class="btn2"
    				 onclick="document.myForm.subject.focus();">
    				<input type="button" value="작성취소" class="btn2"
    				 onclick="javascript:location.href='<%=cp %>/List.jsp'">
    			</div><!-- #bbsCreated_footer -->
    		
    		</div><!-- #bbsCreated -->
    	
    	</form>
    	
    </div><!-- #bbs -->
    
    </body>
    </html>
    • Created_ok.jsp
    더보기
    <%@page import="com.test.BoardDTO"%>
    <%@page import="com.test.BoardDAO"%>
    <%@page import="com.util.DBConn"%>
    <%@page import="java.sql.Connection"%>
    <%@ page contentType="text/html; charset=UTF-8"%>
    <%
    	// Created_ok.jsp
    
    	request.setCharacterEncoding("UTF-8");
    	String cp = request.getContextPath();
    %>
    <%-- 내 풀이 ①
    <%
    	// 이전페이지(Created.jsp)로부터 데이터 수신
    	String subject = request.getParameter("subject");
    	String name = request.getParameter("name");
    	String email = request.getParameter("email");
    	String content = request.getParameter("content");
    	String pwd = request.getParameter("pwd");
    	
    	// textarea 개행 처리
    	content = content.replaceAll("\n", "<br>");
    	
    	// 결과 처리 addr
    	String addr = "";
    	
    	// insertData 를 위한 dto 객체 구성
    	// + num / ipaddr 필요!!!
    	
    	Connection conn = DBConn.getConnection();
    	BoardDAO dao = new BoardDAO(conn);
    	
    	// num 구하기 
    	int num = dao.getMaxNum() + 1;
    	
    	// ipaddr 구하기
    	String ipAddr = request.getRemoteAddr();
    	
    	BoardDTO dto = new BoardDTO();
    	// NUM,NAME,PWD,EMAIL,SUBJECT, CONTENT, IPADDR
    	dto.setNum(num);
    	dto.setName(name);
    	dto.setPwd(pwd);
    	dto.setEmail(email);
    	dto.setSubject(subject);
    	dto.setContent(content);
    	dto.setIpAddr(ipAddr);
    
    	int result = dao.insertData(dto);
    	
    	if (result<1)
    		addr = "";
    	else
    		addr = "List.jsp";
    	
    	DBConn.close();
    	
    	response.sendRedirect(addr);
    %>
    --%>
    <!-- 방법 ② -->
    <jsp:useBean id="dto" class="com.test.BoardDTO" scope="page"></jsp:useBean>
    <jsp:setProperty property="*" name="dto" />
    <%
    	Connection conn = DBConn.getConnection();
    	BoardDAO dao = new BoardDAO(conn);
    	
    	// 게시물 현재 상태의 최대 값 얻어오기
    	int maxNum = dao.getMaxNum();
    	
    	// 게시물 번호 최대값에 1을 더해서 set 하는 과정 → dto 에 추가
    	// dto 객체의 속성값 갱신
    	dto.setNum(maxNum+1);
    	
    	// IP Address 확인
    	// → request.getRemoteAddr(); → 클라이언트(브라우저)의 IP Address 확인 → dto 에 추가
    	dto.setIpAddr(request.getRemoteAddr());
    	
    	//-- 여기까지 수행하면
    	//   insert 쿼리문을 수행하기 위해 필요한 dto 객체의 모든 속성 구성 완료
    	dao.insertData(dto);
    	
    	DBConn.close();
    	
    	//response.sendRedirect("List.jsp");
    	response.sendRedirect(cp + "/List.jsp");
    	
    %>
    <!-- 방법1에서 사용 -->  
    <!-- 
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Created_ok.jsp</title>
    <link rel="stylesheet" type="text/css" href="css/main.css">
    </head>
    <body>
    
    	실패 실패 티비~
    
    </body>
    </html>
    -->
    • Article.jsp
    더보기
    <%@page import="com.test.BoardDTO"%>
    <%@page import="com.test.BoardDAO"%>
    <%@page import="com.util.DBConn"%>
    <%@page import="java.sql.Connection"%>
    <%@ page contentType="text/html; charset=UTF-8"%>
    <%
    	request.setCharacterEncoding("UTF-8");
    	String cp = request.getContextPath();
    %>
    <%
    	Connection conn = DBConn.getConnection();
    	BoardDAO dao = new BoardDAO(conn);
    	
    	// 이전 페이지(List.jsp → 목록페이지)로부터 데이터 수신
    	// → pageNum, num
    	String pageNum = request.getParameter("pageNum");	//-- 페이지 번호
    	String strNum = request.getParameter("num");		//-- 게시물 번호
    	
    	int num = Integer.parseInt(strNum);
    	
    	// 해당 게시물의 조회수 증가
    	dao.updateHitCount(num);
    	
    	// 이전 게시물, 다음 게시물 번호 확인
    	int beforeNum = dao.getBeforeNum(num);				//--  ?? 32
    	int nextNum = dao.getNextNum(num);					//--     32 ??
    
    	BoardDTO dtoBefore = null;
    	BoardDTO dtoNext = null;
    	
    	if (beforeNum != -1)		// 이전 게시물 번호가 null 이 아닌 상황(즉, 존재)
    		dtoBefore = dao.getReadData(beforeNum);
    
    	if (nextNum != -1)			// 다음 게시물 번호가 null 이 아닌 상황(즉, 존재)
    		dtoNext = dao.getReadData(nextNum);
    	
    	// 해당 게시물의 상세 내용 가져오기
    	BoardDTO dto = dao.getReadData(num);
    	
    	// 해당 게시물의 본문 라인 수 확인
    	int lineSu = dto.getContent().split("\n").length;
    	
    	// 게시물 내용 사전 처리
    	dto.setContent(dto.getContent().replaceAll("\n", "<br>"));
    	//-- 안녕하세요\n반갑습니다.\n즐거운하루를\n만들어봅시다.\n안녕히 가세요.			→ getContent()
    	//								↓ (갱신)
    	//-- 안녕하세요<br>반갑습니다.<br>즐거운하루를<br>만들어봅시다.<br>안녕히 가세요.	→ setContent()
    	
    %>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Article.jsp</title>
    <link rel="stylesheet" type="text/css" href="<%=cp %>/css/style.css">
    <link rel="stylesheet" type="text/css" href="<%=cp %>/css/article.css">
    
    
    
    </head>
    <body>
    
    <div id="bbs">
    
    	<div id="bbs_title">
    		게 시 판 (JDBC 연동 버전)
    	</div>
    	
    	<div id="bbsArticle">
    	
    		<div id="bbsArticle_header">
    			<!-- 게시물의 제목입니다. -->
    			<%=dto.getSubject() %>
    		</div><!-- #bbsArticle_header -->
    	
    		<div class="bbsArticle_bottomLine">
    			<dl>
    				<dt>작성자</dt>
    				<!-- <dd>건우팍</dd> -->
    				<dd><%=dto.getName() %></dd>
    				
    				<dt>라인수</dt>
    				<!-- <dd>13</dd> -->
    				<dd><%=lineSu %></dd>
    			</dl>
    		</div><!-- .bbsArticle_bottomLine -->
    	
    		<div class="bbsArticle_bottomLine">
    			<dl>
    				<dt>등록일</dt>
    				<!-- <dd>2023-05-30</dd> -->
    				<dd><%=dto.getCreated() %></dd>
    				
    				<dt>조회수</dt>
    				<!-- <dd>5</dd> -->
    				<dd><%=dto.getHitCount() %></dd>
    			</dl>
    		</div><!-- .bbsArticle_bottomLine -->
    	
    		<div id="bbsArticle_content">
    			<table style="width:600px;">
    				<tr>
    					<td style="padding: 10px 40px 10px 10px; vertical-align: top; height: 150px;">
    						<!-- 어쩌구 저쩌구 이러쿵 저러쿵 한 내용입니다. -->
    						<%=dto.getContent() %>
    					</td>
    				</tr>
    			</table>
    		</div><!-- #bbsArticle_content -->
    			
    		<div class="bbsArticle_bottomLine">
    			<!-- 이전글 : (104) 취미 관련 게시물 -->
    			<%
    			if (beforeNum != -1)	// 이전 게시물이 존재하는 상황
    			{
    			%>
    				<a href="<%=cp %>/Article.jsp?pageNum=<%=pageNum %>&num=<%=beforeNum %>">
    				이전글 : (<%=beforeNum %>) <%=dtoBefore.getSubject() %></a>
    			<%
    			}
    			else					// 이전 게시물이 존재하지 않는 상황
    			{
    			%>
    				이전글 : 없음
    			<%
    			}
    			%>
    			
    			
    		</div><!-- .bbsArticle_bottomLine -->
    		
    		<div class="bbsArticle_noLine">
    			<!-- 다음글 : (102) 날씨 관련 게시물 --> 
    			<%
    			if (nextNum != -1)		// 다음 게시물이 존재하는 상황
    			{
    			%>
    				<a href="<%=cp %>/Article.jsp?pageNum=<%=pageNum %>&num=<%=nextNum %>">
    				다음글 : (<%=nextNum %>)  <%=dtoNext.getSubject() %></a>
    			<%
    			}
    			else					// 다음 게시물이 존재하지 않는 상황
    			{
    			%>
    				다음글 : 없음
    			<%
    			}
    			%>
    			
    		</div><!-- .bbsArticle_noLine -->
    		
    	</div><!-- #bbsArticle -->
    	
    	<div class="bbsArticle_noLine" id="address">
    		<!-- From : 211.238.142.62	 -->
    		From : <%=dto.getIpAddr() %>	
    	</div><!-- .bbsArticle_noLine -->	
    
    	<div id="bbsArticle_footer">
    	
    		<div id="leftFooter">
    			<input type="button" value="수정" class="btn2"
    			 onclick="javascript:location.href='<%=cp%>/Updated.jsp?pageNum=<%=pageNum%>&num=<%=num %>&status=1'">	
    			 <!-- updated 폼에서 삭제도 같이 진행 -->	
    			<input type="button" value="삭제" class="btn2" 
    			onclick="javascript:location.href='<%=cp%>/Updated.jsp?pageNum=<%=pageNum%>&num=<%=num %>&status=2'">		
    		</div><!-- #leftFooter -->
    		
    		<div id="rightFooter">
    			<input type="button" value="리스트" class="btn2" 
    			onclick="javascript:location.href='<%=cp%>/List.jsp?pageNum=<%=pageNum %>'">
    		</div><!-- #rightFooter -->
    	
    	</div><!-- #bbsArticle_footer -->
    
    
    
    </div><!-- #bbs -->
    
    </body>
    </html>
    • Updated.jsp
    더보기
    <%@page import="com.test.BoardDTO"%>
    <%@page import="com.test.BoardDAO"%>
    <%@page import="com.util.DBConn"%>
    <%@page import="java.sql.Connection"%>
    <%@ page contentType="text/html; charset=UTF-8"%>
    <%
    	request.setCharacterEncoding("UTF-8");
    	String cp = request.getContextPath();
    %>
    <%
    	// 게시물 수정 액션 요청 시 넘어온 데이터를 수신하여 처리
    	int num = Integer.parseInt(request.getParameter("num"));
    	String pageNum = request.getParameter("pageNum");
    	
    	// 삭제 액션 요청 처리 과정에서 추가한 속성값 수신
    	// status 1: 업데이트 2: 삭제
    	String statusStr = request.getParameter("status");
    	int status= Integer.parseInt(statusStr); 
    	
    	Connection conn = DBConn.getConnection();
    	BoardDAO dao = new BoardDAO(conn);
    	
    	BoardDTO dto = dao.getReadData(num);
    	
    	String emailStr = "";
    	
    	if (dto.getEmail()!=null)
    		emailStr = dto.getEmail();
    	
    	DBConn.close();
    	
    	// check!!!	
    	// 없는 번호를 직접 주소창에 입력할 때 - 에러페이지를 안 만나게 하기 위해서
    	/*
    	if (dto==null)
    		response.sendRedirect(cp+"/List.jsp");
    	*/
    %>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Updated.jsp</title>
    <link rel="stylesheet" type="text/css" href="<%=cp %>/css/style.css">
    <link rel="stylesheet" type="text/css" href="<%=cp %>/css/created.css">
    <script type="text/javascript" src="<%=cp %>/js/util.js"></script>
    <script type="text/javascript">
    	function sendIt()
    	{
    		f = document.myForm;
    		
    		// 제목 입력 확인 -------------------------------------
    		// 필수 입력 항목 기재 여부 확인 및 공백 처리
    		
    		str = f.subject.value;
    		str = str.trim();
    		
    		// 테스트
    		//alert("|" + str + "|");
    		
    		if (!str)
    		{
    			alert("\n제목을 입력하세요~!!!");
    			f.subject.focus();
    			return;
    		}
    		// ------------------------------------- 제목 입력 확인
    
    		// 이름 입력 확인 -------------------------------------
    		// 필수 입력 항목 기재 여부 확인 및 공백 처리
    		str = f.name.value;
    		str = str.trim();
    		
    		if (!str)
    		{
    			alert("\n작성자 이름을 입력하세요~!!!");
    			f.name.focus();
    			return;
    		}
    		// ------------------------------------- 이름 입력 확인
    
    		// 이메일 검사 ----------------------------------------
    		// 필수 입력 항목이 아니므로 선택적인 입력이 가능하지만
    		// 입력을 한 상황이라면,
    		// 이메일 형식에 맞게 입력했는지 확인하는 처리
    		if (f.email.value)	// 이메일 항목에 내용을 입력한 상황이라면...
    		{
    			if (!isValidEmail(f.email.value))	// 유효한 형태가 아니라면!
    			{
    				alert("\n정상적인 이메일 형식을 입력하세요!");
    				f.email.focus();
    				return;
    			}			
    		}
    		// ---------------------------------------- 이메일 검사
    		
    		// 내용 입력 확인 -------------------------------------
    		// 필수 입력 항목 기재 여부 확인 및 공백 처리
    		str = f.content.value;
    		str = str.trim();
    		
    		if (!str)
    		{
    			alert("\n내용을 입력하세요");
    			f.content.focus();
    			return;
    		}
    		// ------------------------------------- 내용 입력 확인
    	
    		// 패스워드 입력 확인 ---------------------------------
    		// 필수 입력 항목 기재 여부 확인 및 공백 처리
    		str = f.pwd.value;
    		str = str.trim();
    		
    		if (!str)
    		{
    			alert("\n패스워드를 입력하세요!");
    			f.pwd.focus();
    			return;
    		}		
    		// --------------------------------- 패스워드 입력 확인
    
    		// 추가~	
    		// 패스워드 일치 여부 확인 ----------------------------
    		// 입력이 되었다면 패스워드 일치여부 확인
    		// 게시물 작성 시 설정한 패스워드와
    		// 게시물 수정하는 과정에서 입력한 패스워드가
    		// 서로 일치하는 지를 확인하여 액션 처리 수행 여부 판단.
    		if (str!=f.pwdSource.value)
    		{
    			alert("\n패스워드가 일치하지 않습니다.");
    			f.pwd.focus();
    			return;
    		}
    		// ---------------------------- 패스워드 일치 여부 확인
    		
    		// 테스트 
    		//alert("체크 완료!");
    		
    		// 폼의 액션 속성 채워넣기
    		f.action = "<%=cp %>/Updated_ok.jsp";
    		
    		f.submit();
    	}
    	
    	function removeIt()
    	{
    		f = document.myForm;
    		
    		// 패스워드 입력 확인 ---------------------------------
    		// 필수 입력 항목 기재 여부 확인 및 공백 처리
    		str = f.pwd.value;
    		str = str.trim();
    		
    		if (!str)
    		{
    			alert("\n패스워드를 입력하세요!");
    			f.pwd.focus();
    			return;
    		}		
    		// --------------------------------- 패스워드 입력 확인
    
    		// 추가~	
    		// 패스워드 일치 여부 확인 ----------------------------
    		// 입력이 되었다면 패스워드 일치여부 확인
    		// 게시물 작성 시 설정한 패스워드와
    		// 게시물 수정하는 과정에서 입력한 패스워드가
    		// 서로 일치하는 지를 확인하여 액션 처리 수행 여부 판단.
    		if (str!=f.pwdSource.value)
    		{
    			alert("\n패스워드가 일치하지 않습니다.");
    			f.pwd.focus();
    			return;
    		}
    		// ---------------------------- 패스워드 일치 여부 확인
    		
    		// 폼의 액션 속성 채워넣기
    		f.action = "<%=cp %>/Delete_ok.jsp";
    		
    		f.submit();
    	}
    </script>
    </head>
    <body>
    
    <div id="bbs">
    	
    	<div id="bbs_title">
    		게 시 판 (JDBC 연동 버전)
    	</div>
    	
    	<!-- <form action="Created_ok.jsp" method="post" name="myForm"> --> <!-- action 값 지정시 -->
    	<form action="" method="post" name="myForm">
    		<div id="bbsCreated">
    			
    			<div class="bbsCreated_bottomLine">
    				<dl>
    					<dt>제&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;목</dt>
    					<dd>
    						<%
    						if (status==1)	// 수정 액션 처리
    						{
    						%>
    						<input type="text" name="subject" size="64" maxlength="100" class="boxTF"
    						value="<%=dto.getSubject()%>">
    						<%
    						}
    						else	// 삭제 액션 처리
    						{
    						%>
    						<input type="text" name="subject" size="64" maxlength="100" class="boxTF"
    						value="<%=dto.getSubject()%>"  disabled="disabled"
    						style="background-color: #DBDBDB">
    						<%
    						}
    						%>
    					</dd>
    				</dl>
    			</div><!-- .bbsCreated_bottmLine -->
    		
    			<div class="bbsCreated_bottomLine">
    				<dl>
    					<dt>작 성 자</dt>
    					<dd>
    						<%
    						if (status==1)
    						{
    						%>
    						<input type="text" name="name" size="35" maxlength="20" class="boxTF"
    						value="<%=dto.getName()%>">
    						<%
    						}
    						else
    						{
    						%>
    						<input type="text" name="name" size="35" maxlength="20" class="boxTF"
    						value="<%=dto.getName()%>"  disabled="disabled"
    						style="background-color: #DBDBDB">
    						<%
    						}
    						%>
    					</dd>
    				</dl>
    			</div><!-- .bbsCreated_bottmLine -->
    		
    			<div class="bbsCreated_bottomLine">
    				<dl>
    					<dt>이 메 일</dt>
    					<dd>
    						<%
    						if (status==1)
    						{
    						%>
    						<input type="email" name="email" size="35" maxlength="50" class="boxTF"
    						value="<%=emailStr %>">
    						<%
    						}
    						else
    						{
    						%>
    						<input type="email" name="email" size="35" maxlength="50" class="boxTF"
    						value="<%=emailStr %>"  disabled="disabled"
    						style="background-color: #DBDBDB">
    						<%
    						}
    						%>
    					</dd>
    				</dl>
    			</div><!-- .bbsCreated_bottmLine -->
    
    			<div id="bbsCreated_content">
    				<dl>
    					<dt>내&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;용</dt>
    					<dd>
    						<%
    						if (status==1)
    						{
    						%>
    						<!-- check!!! 1. value 속성이 없음(사이에기입) 2.띄어쓰기나 개행되지않게 주의 -->
    						<textarea rows="12" cols="63" name="content" class="boxTA"
    						><%=dto.getContent() %></textarea>
    						<%
    						}
    						else
    						{
    						%>
    						<textarea rows="12" cols="63" name="content" class="boxTA" disabled="disabled" 
    						 style="background-color: #DBDBDB" ><%=dto.getContent() %></textarea>
    						<%
    						}
    						%>
    					</dd>
    				</dl>
    			</div><!-- #bbsCreated_content -->
    			
    			<div class="bbsCreated_noLine">
    				<dl>
    					<dt>패스워드</dt>
    					<dd>
    						<!-- check : hidden 으로 숨겨두고 입력한 패스워드를 확인해서 수정submit ok 하기 -->
    						<!-- pwd 값을 hidden으로 숨겨도 데이터 찾아낼 수 있기 때문에 실무에서는 key-value 로 값을 찾아내서 비교하는 방식을 사용한다. -->
    						<input type="hidden" name="pwdSource" value="<%=dto.getPwd() %>">
    						<input type="password" name="pwd" size="35" maxlength="10" class="boxTF">
    						<span style="font-size: 6pt;">(게시물 수정 및 삭제 시 필요)</span>
    					</dd>
    				</dl>
    			</div><!-- .bbsCreated_noLine -->			
    		
    			<div id="bbsCreated_footer">
    			
    				<!-- Updater_ok.jsp 페이지 요청 과정에서 추가로 필요한 데이터 -->
    				<!-- 게시물 번호 -->
    				<input type="hidden" name="num" value="<%=dto.getNum() %>">
    				<input type="hidden" name="pageNum" value="<%=pageNum %>">
    				
    				<%	if (status==1) { %>
    				<input type="button" value="수정하기" class="btn2" onclick="sendIt()">
    				<input type="reset" value="다시입력" class="btn2"
    				 onclick="document.myForm.subject.focus();">
    				<input type="button" value="작성취소" class="btn2"
    				 onclick="javascript:location.href='<%=cp %>/List.jsp?pageNum=<%=pageNum %>'">
    				<% } else { %>
    				<input type="button" value="삭제하기" class="btn2" onclick="removeIt()">
    				
    				<input type="button" value="삭제취소" class="btn2"
    				 onclick="javascript:location.href='<%=cp %>/List.jsp?pageNum=<%=pageNum %>'">				
    				<% } %>
    			</div><!-- #bbsCreated_footer -->
    		
    		</div><!-- #bbsCreated -->
    	
    	</form>
    	
    </div><!-- #bbs -->
    
    </body>
    </html>
    • Updated_ok.jsp
    더보기
    <%@page import="com.test.BoardDTO"%>
    <%@page import="com.test.BoardDAO"%>
    <%@page import="com.util.DBConn"%>
    <%@page import="java.sql.Connection"%>
    <%@ page contentType="text/html; charset=UTF-8"%>
    <%
    	// Updated_ok.jsp
    
    	request.setCharacterEncoding("UTF-8");
    	String cp = request.getContextPath();
    %>
    <jsp:useBean id="dto" class="com.test.BoardDTO" scope="page"></jsp:useBean>
    <jsp:setProperty property="*" name="dto" />
    <%
    	// 위의 액션 태그를 통해 dto 의 속성 값들을 이전페이지로부터 수신
    	// 넘겨받은 데이터 + 페이지번호(pageNum)
    	String pageNum = request.getParameter("pageNum");
    
    	Connection conn = DBConn.getConnection();
    	BoardDAO dao = new BoardDAO(conn);
    	
    	int result = dao.updateData(dto);
    	
    	// result 값에 따른 분기 처리 가능
    	
    	DBConn.close();
    	
    	response.sendRedirect(cp + "/List.jsp?pageNum="+pageNum);
    	
    %>
    • Delete_ok.jsp
    더보기
    <%@page import="com.test.BoardDTO"%>
    <%@page import="com.test.BoardDAO"%>
    <%@page import="com.util.DBConn"%>
    <%@page import="java.sql.Connection"%>
    <%@ page contentType="text/html; charset=UTF-8"%>
    <%
    	// Delete_ok.jsp
    
    	request.setCharacterEncoding("UTF-8");
    	String cp = request.getContextPath();
    %>
    <%
    	// 이전 페이지(Updated.jsp) 에서 전달받은 데이터 + pageNum
    	String pageNum = request.getParameter("pageNum");
    	String num = request.getParameter("num");
    	
    	Connection conn = DBConn.getConnection();
    	BoardDAO dao = new BoardDAO(conn);
    	
    	int result = dao.deleteData(Integer.parseInt(num));
    	
    	// result 결과값에 따른 분기 가능
    	
    	response.sendRedirect(cp+"/List.jsp?pageNum="+pageNum);
    
    %>
    • created.css
    더보기
    @charset "UTF-8";
    
    #bbs
    {
    	width: 600px;
    	margin: 30px auto;
    	text-align: left;
    }
    
    #bbs_title
    {
    	width: 574px;
    	padding-left: 20px;
    	height: 40px;
    	border: 3px solid #D6D4D6;
    	text-align: left;
    	font-weight: bold;
    	line-height: 40px;
    	font-size: 10pt;
    	margin-bottom: 30px;	
    }
    
    #bbsCreated
    {
    	width: 600px;
    	overflow:  visible;
    	border-top: 3px solid #DBDBDB;
    	border-bottom: 3px solid #DBDBDB;
    	text-align: left;
    }
    
    .bbsCreated_bottomLine
    {
    	height: 35px;
    	line-height: 35px;
    	border-bottom: 1px solid #DBDBDB;
    	clear: both;
    	text-align: left;
    }
    
    .bbsCreated_noLine
    {
    	height: 35px;
    	line-height: 35px;
    	clear: both;
    	text-align: left;	
    }
    
    #bbsCreated_content
    {
    	height: 170px;
    	line-height: 170px;
    	border-bottom: 1px solid #DBDBDB;
    	clear: both;
    	text-align: left;	
    }
    
    #bbsCreated dt
    {
    	float: left;
    	height: 35px;
    	width: 80px;
    	line-height: 35px;
    	text-align: left;
    	padding-left: 20px;
    	background-color: #EEEEEE;
    }
    
    #bbsCreated dd
    {
    	float: left;
    	height: 35px;
    	width: 440px;
    	line-height: 35px;
    	text-align: left;
    	padding-left: 10px;
    }
    
    #bbsCreated_content dt
    {
    	float: left;
    	height: 170px;
    	width: 80px;
    	text-align: left;
    	padding-left: 20px;
    	background-color: #EEEEEE;
    }
    
    #bbsCreated_content dd
    {
    	float: left;
    	height: 170px;
    	width: 440px;
    	line-height: 170px;
    	text-align: left;
    	padding-left: 10px;
    }
    
    #bbsCreated_footer
    {
    	width : 600px;
    	overflow: visible;
    	clear: both;
    	height: 50px;
    	line-height: 50px;
    	margin-bottom: 20px;
    	text-align: center;
    }
    • list.css
    더보기
    @charset "UTF-8";
    
    #bbsList
    {
    	width: 690px;
    	margin: 30px auto;
    	text-align: left;
    }
    
    #bbsList_title
    {
    	width: 664px;
    	padding-left: 20px;
    	height: 40px;
    	border: 3px solid #D6D4D6;
    	text-align: left;
    	font-weight: bold;
    	line-height: 40px;
    	font-size: 10pt;
    	margin-bottom: 30px; 
    }
    
    #bbsList_header
    {
    	height: 27px;
    }
    
    #bbsList_header #leftHeader
    {
    	float: left;
    	width: 345px;
    	text-align: left;
    }
    
    #bbsList_header #rightHeader
    {
    	float: right;
    	width: 345px;
    	text-align: right;
    }
    
    #bbsList_Header .selectField
    {
    	border: 1px solid;
    	border-color: #666666;
    	background-color: #ffffff;
    	font-family: 굴림;
    	font-size: 9pt;
    	height: 20px; 
    }
    
    #bbsList_Header .textField
    {
    	border: 1px solid;
    	height: 13px;
    	padding: 2px 2px 2px 2px;
    	border-color: #666666;
    	background-color: #ffffff;
    	font-family: 굴림;
    	font-size: 9pt;
    }
    
    #bbsList_list
    {
    	clear: both;
    }
    
    #bbsList_list dd
    {
    	float: left;
    	height: 27px;
    	line-height: 27px;
    	text-align: center;
    }
    
    #bbsList_list #title
    {
    	height: 30px;
    	border-top: 1px solid #CCCCCC;
    	border-bottom: 1px solid #CCCCCC;
    	background-color: #E6E4E6;
    }
    
    #bbsList_list #title dl
    {
    	height: 27px;
    	border-left: 0px solid #5db062;
    	border-right: 0px solid #5db062;
    }
    
    #bbsList_list #title dt
    {
    	float: left;
    	line-height: 34px;
    	text-align: center;
    }
    
    #bbsList_list .num {width: 50px;}
    #bbsList_list .subject {width: 420px;}
    #bbsList_list .name {width: 90px;}
    #bbsList_list .created {width: 65px;}
    #bbsList_list .hitCount {width: 60px;}
    
    #bbsList_list #lists
    {
    	clear: both;
    }
    
    #bbsList_list #lists dl
    {
    	float: left;
    	border-bottm: 1px solid #E4E4E4;
    }
    
    #bbsList_list #lists dd.created
    {
    	font-size: 7pt;
    }
    
    #bbsList_list dd.subject
    {
    	width: 410px;
    	margin-left: 10px;
    	text-align: left;
    }
    
    #bbsList_list a
    {
    	line-height: 27px;
    }
    
    #bbsList_list #footer
    {
    	clear: both;
    	height: 32px;
    	line-height: 32px;
    	margin-top: 5px;
    	text-align: center;
    }
    • style.css
    더보기
    @charset "UTF-8";
    
    *
    {
    	margin: 0px;
    	padding: 0px;
    }
    
    body
    {
    	font-size: 9pt;
    	/* font-family: 돋움; */
    }
    
    a
    {
    	cursor: pointer;
    	color: #000000;
    	text-decoration: none;
    	font-size: 9pt;
    	line-height: 150%;
    }
    
    a:hover, a:active
    {
    	font-size: 9pt;
    	color: #F28011;
    	text-decoration: underline;
    }
    
    ul
    {
    	list-style: none;
    }
    
    td
    {
    	font-size: 9pt;
    }
    
    .btn1
    {
    	font-size: 9pt;
    	color : rgb(0,0,0);
    	background-color: : rgb(245,245,245);
    	line-height: 16px;
    	padding: 1px 3px 1px 3px;
    }
    
    .btn2
    {
    	color: #000000;
    	/* font: normal 9pt '돋움'; */
    	font: normal 9pt;
    	background-color: #E4E4E4;
    	border: 1px solid;
    	border-color: #696 #363 #363 #696;
    	line-height: 16px;
    	padding: 1px 6px 1px 6px; 
    }
    
    .btn2:hover
    {
    	color: white;
    	background-color: #787;
    }
    
    .btn3
    {
    	color: rgb(255,255,255);
    	/* font: normal 9pt '돋움'; */
    	font: normal 9pt ;
    	border: 1px solid;
    	background-color: #4C4C4C;
    	line-height: 16px;
    	padding: 1px 6px 1px 6px;
    }
    
    .boxTF
    {
    	border: 1px solid #666666;
    	height: 15px;
    	margin-top: 3px;
    	padding: 2px 2px 2px 2px;
    	background-color: #ffffff;
    	/* font-family: 돋움; */
    	font-size: 9pt;
    }
    
    .boxTA
    {
    	border: 1px solid #666666;
    	height: 150px;
    	margin-top: 3px;
    	padding: 2px 2px 2px 2px;
    	background-color: #ffffff;
    	/* font-family: 돋움; */
    	font-size: 9pt;
    }
    
    .selectField
    {
    	border: 1px solid #666666;
    	background-color: #ffffff;
    	/* font-family: 돋움; */
    	font-size: 9pt;
    }
    
    .line1 {height: 1px; font-size: 0pt; padding: 0px;}
    .line2 {height: 2px; font-size: 0pt; padding: 0px;}
    .line3 {height: 3px; font-size: 0pt; padding: 0px;}
    • util.js
    더보기
    //***********************************************************************
    /*=====================
       유틸리티 (util.js)
    =====================*/
    
    // 내용의 값의 빈공백을 trim(앞/뒤)
    String.prototype.trim = function()
    {
    	var TRIM_PATTERN = /(^\s*)|(\s*$)/g;
    	return this.replace(TRIM_PATTERN, "");
    };
    
    // 이메일 형식 검사
    function isValidEmail(data)
    {
    	var format = /^((\w|[\-\.])+)@((\w|[\-\.])+)\.([A-Za-z]+)$/;
    	if (data.search(format) != -1)
    		return true; //-- 올바른 포맷 형식
    	return false;
    }
    
    
    // 한글 필터링
    function isValidKorean(data)
    {
        // UTF-8 코드 중 AC00 부터 D7A3 값인지 검사
    	var format = /^[\uac00-\ud7a3]*$/g;
    	if (data.search(format) == -1)
    		return false; 
    	return true; //-- 올바른 포맷 형식
    }
    
    
    // 이미지 파일인지 검사
    function isImageFile(fileName)
    {
    	if(!/(\.gif|\.jpg|\.jpeg|\.png)$/i.test(fileName)) 
    	{
    		return false;
    	}
    	return true;
    }
    
    // 숫자인지 검사
    function isValidNumber(data)
    {
    	var format=/^[0-9]*$/g;
    	if(data.search(format) == -1)
    		return false;
    	return true;
    }
    
    //***********************************************************************
    /*============================
       날짜 관련 함수 (util.js)
    ============================*/
    
    // 날짜 형식 검사 정규표현식 (2011-03-01 기준)
    function isValidDateFormat(data)
    {
    	var format = /[12][0-9]{3}-[0-9]{2}-[0-9]{2}/;
    	if(data.search(format) == -1)
    		return false;
    		
    	var _year = data.substr(0,4);
    	var _month= data.substr(5,2);
    	var _day = data.substr(8,2);
    	
    	return isValidDate(_year, _month, _day);		
    }
    
    // 날짜가 정확한지 검사(문자)
    function isValidDate(y, m, d)
    {
    	var year, month, day;
    	var days = new Array (31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
    
    	y = y.trim();
    	m = m.trim();
    	d = d.trim();
    	if(y.length != 4 || m.length!=2 || d.length!=2)
    		return false;
    
    	year = parseInt(y);
    
    	if(m.charAt(0) == '0')
    		m = m.charAt(1);
    	month = parseInt(m);
    
    	if(d.charAt(0) == '0')
    		d = d.charAt(1);
    	day = parseInt(d);
    
    	// 날짜 검사
    	if(year%4==0 && year%100 !=0 || year%400==0)
    		days[1]=29;
    	else
    		days[1]=28;
    
    	if(month < 1 || month > 12)
    		return false;
    
    	if(day < 1 || day > days[month-1])
    		return false;
    
    	return true;
    }
    
    // 두 날짜간의 날수를 계산(형식 : 2011-03-01)
    function getDays(sDate, eDate) 
    {  
        var date1 = new Date(sDate.split('-')[0],sDate.split('-')[1],sDate.split('-')[2]);
        var date2 = new Date(eDate.split('-')[0],eDate.split('-')[1],eDate.split('-')[2]);
    
        var interval = date2 - date1;
        var day = 1000*60*60*24;
        
        return parseInt(interval/day);
    }
    
    //***********************************************************************
    /*============================
       쿠키 설정 (util.js)
    ============================*/
    
    
    function setCookie(name, value, expiredays)
    {
    	var todayDate = new Date();
    	todayDate.setDate(todayDate.getDate() + expiredays);
    	document.cookie = name + "=" + encodeURIComponent(value) + "; path=/; expires=" + todayDate.toGMTString + ";";
    }
    
    // 쿠키값 반환
    function getCookie(name) 
    {
    	var found = false;
    	var start, end=0;
    	var i=0;
    
    	// 쿠키 문자열 전체를 검색
    	while(i <= document.cookie.length) 
    	{
    		start = i;
    		end = start + name.length;
    
    		// name 과 동일한 문자가 있다면
    		if(document.cookie.substring(start, end) == name) 
    		{
    			found = true;
    			break;
    		}
    		i++;
    	}
    
    	// name 문자열을 cookie 에서 찾은 경우
    	if(found == true) 
    	{
    		start = end + 1;
    		end = document.cookie.indexOf(";", start);
    
    		// 마지막 부분이라는 것을 의미(마지막에는 ';'가 없다)
    		if(end < start)
    			end = document.cookie.length;
    
    		return decodeURIComponent(document.cookie.substring(start, end));
    	}
    
    	return "";
    }
    
    //***********************************************************************
    /*=================================
       주민등록 번호 검사 (util.js)
    =================================*/
    
    // 주민등록 번호 검사
    function isValidResidentNO(ssn1, ssn2) 
    {
    	var days = new Array (31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
    
    	var check = new Array (2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4, 5);
    	var ssn = new Array(13);
    	var temp, year, month, day, tot, chkNum, i;
    
    	if((ssn1.length != 6) || (ssn2.length != 7))
    		return false;
    
    	for(i = 0; i< 13; i++) 
    	{
    		if(i < 6)
    			ssn[i] = parseInt(ssn1.charAt(i));
    		else
    			ssn[i] = parseInt(ssn2.charAt(i-6));
    	}
    
    	temp = ssn1.substr(0, 2);
    	if(temp.charAt(0) == '0')
    		temp = temp.charAt(1);
    	year = parseInt(temp);
    
    	if(ssn[6] == 1 || ssn[6] == 2)
    		year = year + 1900;
    	else
    		year = year + 2000;
    
    	temp = ssn1.substr(2, 2);
    	if(temp.charAt(0) == '0')
    		temp = temp.charAt(1);
    	month = parseInt(temp);
    
    	if(ssn[6] < 1 || ssn[6] > 4)
    		return false;
       
    	temp = ssn1.substr(4, 2);
    	if(temp.charAt(0) == '0')
    		temp = temp.charAt(1);
    	day = parseInt(temp);
    
    	if(year%4==0 && year%100!=0 || year%400==0)
    		days[1]=29;
    	else
    		days[1]=28;
    
    	if(month < 1 || month > 12)
    		return false;
    
    	if(day > days[month-1] || day < 1)
    		return false;
    
    	tot=0;
    	for(i=0; i<12; i++)
    		tot = tot + ssn[i] * check[i];
    	chkNum = 11 - tot % 11;
    	chkNum = chkNum % 10;
      
    	if(chkNum != ssn[12])
    		return false;
    	return true;
    }
    
    //***********************************************************************
    /*============================
       입력 허용 (util.js)
    ============================*/
    
    // 숫자와 영문자만 입력 허용
    function onlyAlpNum() 
    {
    	if((event.keyCode < 48) || 
    		((event.keyCode > 57) && (event.keyCode < 65)) || 
    		((event.keyCode > 90) && (event.keyCode < 97)) || 
    		(event.keyCode > 122)) 
    	{
    		if(navigator.appName=="Netscape")
    			event.preventDefault();
    		else
    			event.returnValue = false;
    	}
    }
    
    // 숫자만 입력 허용
    function onlyNum() 
    {
    	if((event.keyCode < 48) || (event.keyCode > 57)) 
    	{
    		if(navigator.appName=="Netscape")
    			event.preventDefault();
    		else
    			event.returnValue = false;
    	}
    }
    
    // 한글만 입력 허용
    function onlyHangul() 
    {
    	if((event.keyCode < 12592) || (event.keyCode > 12687)) 
    	{
    		if(navigator.appName=="Netscape")
    			event.preventDefault();
    		else
    			event.returnValue = false;
    	}
    }
    
    //***********************************************************************
    /*============================
       팝업 윈도우즈 (util.js)
    ============================*/
    
    // 팝업 윈도우즈
    function winOpen(theURL, winName) 
    {
    	var flag;
    	flag = "left=10, ";
    	flag += "top=10, ";
    	flag += "width=372, ";
    	flag += "height=466, ";
    	flag += "toolbar=no, ";
    	flag += "menubar=no, ";
    	flag += "status=no, ";
    	flag += "scrollbars=no, ";
    	flag += "resizable=no";
    	// features = "scrollbars=no,resizable=no,width=220,height=230";
    
    	window.open(theURL, winName, flag);
    
    	return;
    }
    
    //***********************************************************************
    /*============================
       기타 형식 검사 (util.js)
    ============================*/
    
    // 영문, 숫자 인지 확인
    function isValidEngNum(str) 
    {
    	for(var i=0;i<str.length;i++) 
    	{
    		achar = str.charCodeAt(i);                 
    		if( achar > 255 )
    			return false;
    	}
    	return true; 
    }
    
    // 전화번호 형식(숫자-숫자-숫자)인지 체크
    function isValidPhone(data) 
    {
    	var format = /^(\d+)-(\d+)-(\d+)$/;
    	if (data.search(format) == -1)
    		return false;
    	return true;
    }
    
    // 문자열에 특수문자(",  ',  <,  > ) 검사
    function isValidSpecialChar(str) 
    {
    	if(str.value.search(/[\",\',<,>]/g) >= 0)
    		return true; // 존재 하면
    	return false;
    }
    • article.css
    더보기
    @charset "UTF-8";
    
    #bbs
    {
    	width: 600px;
    	margin: 30px auto;
    	text-align: left;
    }
    
    #bbs_title
    {
    	width: 574px;
    	padding-left: 20px;
    	height: 40px;
    	border: 3px solid #D6D4D6;
    	text-align: left;
    	font-weight: bold;
    	line-height: 40px;
    	font-size: 10pt;
    	margin-bottom: 30px;	
    }
    
    #bbsArticle
    {
    	width: 600px;
    	overflow: visible;
    	border-top: 3px solid #E6D4A6;
    	border-bottom: 3px solid #E6D4A6;
    	text-align: left;
    }
    
    #bbsArticle_header
    {
    	height: 35px;
    	line-height: 35px;
    	border-bottom: 2px solid #DBDBDB;
    	text-align: center;
    }
    
    #bbsArticle dt
    {
    	float: left;
    	height: 35px;
    	width: 60px;
    	line-height: 35px;
    	text-align: center;
    	background-color: #EEEEEE;
    }
    
    #bbsArticle dd
    {
    	float: left;
    	height: 35px;
    	width: 230px;
    	line-height: 35px;
    	text-align: left;
    	padding-left: 10px;
    }
    
    .bbsArticle_bottomLine
    {
    	height: 35px;
    	line-height: 35px;
    	border-bottom: 1px solid #DBDBDB;
    	clear: both;
    	text-align: left;
    }
    
    .bbsArticle_noLine
    {
    	height: 35px;
    	line-height: 35px;
    	clear: both;
    	text-align: left;
    }
    
    #bbsArticle_content
    {
    	overflow: visible;
    	border-bottom: 1px solid #DBDBDB;
    	text-align: left;
    	min-height: 250px;
    	padding: 20px;
    }
    
    #bbsArticle_footer
    {
    	clear: both;
    	height: 32px;
    	line-height: 32px;
    	margin-bottom: 20px;
    }
    
    #bbsArticle_footer #leftFooter
    {
    	float: left;
    	width: 300px;
    	text-align: left;
    }
    
    #bbsArticle_footer #rightFooter
    {
    	float: right;
    	width: 300px;
    	text-align: right;
    }
    
    #address
    {
    	text-align: right;
    }

    메모.txt
    0.00MB

    728x90
Designed by planet-si