매일 조금씩

12/30 - JSP(8) : 파일 첨부 되는 model1 게시판 만들기, 톰캣만으로 게시판 실행(배포) 본문

빅데이터 플랫폼 구축을 위한 자바 개발자 양성과정

12/30 - JSP(8) : 파일 첨부 되는 model1 게시판 만들기, 톰캣만으로 게시판 실행(배포)

mezo 2021. 1. 4. 20:02
728x90
반응형

model1

      jsp

      => 공통된 자바 => 클래스화(DAO, TO)

      => 반복에 의한 숙달(정답 X) 

      => 답변형 게시판

              board_list1.jsp  => 나머지 완성 해놓아야함

 

파일 업로드

1. html

       <form method="post" enctype="multipart/form-data">

       <input type="file" name      

       <input type="file" name       

             -> name값만 달리해서 여러개 파일 업로드 하도록 이렇게 해놓으면 ok 페이지에서 알아서 처리함.

                 UploadEx01 > upload_form.jsp 수정

2. cos.jar    (딴것도 있는데 이게 제일 쉽다)

3. jsp

       MultipartRequest

 

 

 

 

 

 

파일 업로드 되는 model1게시판


어제꺼에 이어서  

 4) delete

if(result == 0){
    // 비밀번호 오류
    flag = 1;
}else if(result == 1){
    // 정상
    flag = 0;
    // 실제 파일을 지워줘!
    if(filename != null){
        File file = new File("C:/Java/java/jsp-workspace/BoardEx01/WebContent/upload/" + filename);
        file.delete();
    }
}

실제 파일을 지우는 if 문이 추가 되어야한다.

 

5) modify

ok페이지에서 새 업로드 파일이 있든 없든 받아온다.  

// 새 업로드 파일
String newFilename = multi.getFilesystemName("upload");
long newFilesize = 0;
File newFile = multi.getFile("upload");
if(newFile != null){
    newFilesize = newFile.length();
}

 

기존 파일을 받아온다.

// 기존 파일 받아오기 2
String sql = "select filename from pds_board1 where seq=?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, seq);

rs = pstmt.executeQuery();
String oldFilename = null;
if(rs.next()){
    oldFilename = rs.getString("filename");
}

 

새 업로드 파일이 있을 때와 없을 때 sql 구문을 달리한다.

if(newFilename != null ){
    // 새 업로드 파일이 있을 때 
    sql = "update pds_board1 set subject = ?, mail=?, content=?, filename=?, filesize=? where seq=? and password=?";
    pstmt = conn.prepareStatement(sql);
    pstmt.setString(1, subject);
    pstmt.setString(2, mail);
    pstmt.setString(3, content);
    pstmt.setString(4, newFilename);
    pstmt.setLong(5, newFilesize);
    pstmt.setString(6, seq);
    pstmt.setString(7, password);
}else{
    // 새 업로드 파일이 없을 때
    // 있으나 없으나 위에 걸로 해버리면 기존에 있던 파일이 사라짐
    sql = "update pds_board1 set subject = ?, mail=?, content=? where seq=? and password=?";
    pstmt = conn.prepareStatement(sql);
    pstmt.setString(1, subject);
    pstmt.setString(2, mail);
    pstmt.setString(3, content);
    pstmt.setString(4, seq);
    pstmt.setString(5, password);

}

 

만약 새로운 업로드 파일이 있을 때의 구문 하나로 모두 처리한다면, 

기존 파일이 있고 새로운 업로드 파일이 없을 때 기존 파일이 삭제 된다.

 

 

 

 

4. 파일 업로드 되는 model1게시판

PdsModel1Ex01

1) TO , DAO

package model1;

public class BoardTO {
	private String seq;
	private String subject;
	private String writer;
	private String mail;
	private String password;
	private String content;
	private String hit;
	private String wdate;
	private String wip;
	private int wgap;
	private String filename;
	private long filesize;
	
	public String getFilename() {
		return filename;
	}
	public void setFilename(String filename) {
		this.filename = filename;
	}
	public long getFilesize() {
		return filesize;
	}
	public void setFilesize(long filesize) {
		this.filesize = filesize;
	}
	public String getWip() {
		return wip;
	}
	public void setWip(String wip) {
		this.wip = wip;
	}
	public String getSeq() {
		return seq;
	}
	public void setSeq(String seq) {
		this.seq = seq;
	}
	public String getSubject() {
		return subject;
	}
	public void setSubject(String subject) {
		this.subject = subject;
	}
	public String getWriter() {
		return writer;
	}
	public void setWriter(String writer) {
		this.writer = writer;
	}
	public String getMail() {
		return mail;
	}
	public void setMail(String mail) {
		this.mail = mail;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public String getHit() {
		return hit;
	}
	public void setHit(String hit) {
		this.hit = hit;
	}
	public String getWdate() {
		return wdate;
	}
	public void setWdate(String wdate) {
		this.wdate = wdate;
	}
	public int getWgap() {
		return wgap;
	}
	public void setWgap(int wgap) {
		this.wgap = wgap;
	}
	
	
}
package model1;

import java.io.File;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

public class BoardDAO {
	
	private DataSource dataSource;
	
	public BoardDAO() {
		try {
			Context iniCtx = new InitialContext();
			Context envCtx = (Context)iniCtx.lookup("java:comp/env");
			this.dataSource = (DataSource)envCtx.lookup("jdbc/mariadb2");
		} catch (NamingException e) {
			System.out.println("[에러] " + e.getMessage());
		}
	}
	
	
	// writer - dao 통과 안해도됨
	public void boardWrite() {}
	
	// writer_ok - flag 값있어야함
	public int boardWriteOk(BoardTO to) {
		Connection conn = null;
		PreparedStatement pstmt = null;
		
		// 정상처리 / 비정상 => 결과를 통합처리하기 위한 변수
		int flag = 1;
		
		try{
			conn = dataSource.getConnection();
			
			String sql = "insert pds_board1 values(0, ?, ?, ?, ?, ?, ?, ?, 0, ?, now())";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, to.getSubject());
			pstmt.setString(2, to.getWriter());
			pstmt.setString(3, to.getMail());
			pstmt.setString(4, to.getPassword());
			pstmt.setString(5, to.getContent());
			pstmt.setString(6, to.getFilename());
			pstmt.setLong(7, to.getFilesize());
			pstmt.setString(8, to.getWip());
			
			// 일반적으로 0 값은 정상이다.
			int result = pstmt.executeUpdate();
			if(result == 1){
				flag = 0;
			}
		}catch(SQLException e){
			System.out.println("[에러] : "+e.getMessage());
		}finally{
			if(pstmt != null) try{pstmt.close();} catch(SQLException e) {}
			if(conn != null) try{conn.close();} catch(SQLException e) {}
		}
		
		return flag;
	}
	
	
	// list
	public ArrayList<BoardTO> boardList(){
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		ArrayList<BoardTO> lists = new ArrayList<BoardTO>();
		try{
			conn = dataSource.getConnection();
			
			String sql = "select seq, subject, writer, date_format(wdate,'%Y-%m-%d') wdate, hit, datediff(now(), wdate) wgap, filesize from pds_board1 order by seq desc";
			pstmt = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
			
			rs = pstmt.executeQuery();
			
			while(rs.next()){
				BoardTO to = new BoardTO();
				to.setSeq(rs.getString("seq"));
				to.setSubject(rs.getString("subject"));
				to.setWriter(rs.getString("writer"));
				to.setWdate(rs.getString("wdate"));
				to.setHit(rs.getString("hit"));
				to.setWgap(rs.getInt("wgap"));
				to.setFilesize(rs.getLong("filesize"));
				
				lists.add(to);
			}
		}catch(SQLException e){
			System.out.println("[에러] : "+e.getMessage());
		}finally{
			if(rs != null) try{ rs.close();} catch(SQLException e) {}
			if(pstmt != null) try{ pstmt.close();} catch(SQLException e) {}
			if(conn != null) try{conn.close();} catch(SQLException e) {}
		}
		return lists;
	}
	
	
	// view
	public BoardTO boardView(BoardTO to) {
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
	
		try{
			conn = dataSource.getConnection();
			
			// 조회수 증가를 위한 update
			String sql = "update pds_board1 set hit=hit+1 where seq=?";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, to.getSeq());
			
			pstmt.executeUpdate();
			
			sql = "select subject, writer, mail, wip, wdate, hit,filename, filesize, content from pds_board1 where seq=?";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, to.getSeq());
			
			rs = pstmt.executeQuery();
			// 하나만 가져오니까 if문 사용
			if(rs.next()){
				to.setSubject(rs.getString("subject"));
				to.setWriter(rs.getString("writer"));
				to.setMail(rs.getString("mail"));
				to.setHit(rs.getString("hit"));
				to.setWip(rs.getString("wip"));
				to.setWdate(rs.getString("wdate"));
				to.setFilename(rs.getString("filename"));
				to.setFilesize(rs.getLong("filesize"));
				to.setContent(rs.getString("content"));
				
			}
		
		}catch(SQLException e){
			System.out.println("[에러] : "+e.getMessage());
		}finally{
			if(rs != null) try{rs.close();} catch(SQLException e) {}
			if(pstmt != null) try{pstmt.close();} catch(SQLException e) {}
			if(conn != null) try{conn.close();} catch(SQLException e) {}
		}
		
		return to;
	}
	
	// delete
	public BoardTO boardDelete(BoardTO to) {
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		try{
			conn = dataSource.getConnection();
			
			String sql = "select subject, writer from pds_board1 where seq=?";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, to.getSeq());
			
			rs = pstmt.executeQuery();
			// 하나만 가져오니까 if문 사용
			if(rs.next()){
				to.setSubject(rs.getString("subject"));
				to.setWriter(rs.getString("writer"));
			}
		}catch(SQLException e){
			System.out.println("[에러] : "+e.getMessage());
		}finally{
			if(rs != null) try{rs.close();} catch(SQLException e) {}
			if(pstmt != null) try{pstmt.close();} catch(SQLException e) {}
			if(conn != null) try{conn.close();} catch(SQLException e) {}
		}
		return to;
	}
	
	// delete_ok
	public int boardDeleteOk(BoardTO to) {
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		// 정상처리 / 비정상 => 결과를 통합처리하기 위한 변수
		int flag = 2;
		
		try{
			conn = dataSource.getConnection();
			
			// filename select
			String sql = "select filename from pds_board1 where seq=?";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, to.getSeq());
			
			rs = pstmt.executeQuery();
			String filename = null;
			if(rs.next()){
				filename = rs.getString("filename");
			}
			
			sql = "delete from pds_board1 where seq=? and password=?";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, to.getSeq());
			pstmt.setString(2, to.getPassword());
			
			int result = pstmt.executeUpdate();
			if(result == 0){
				// 비밀번호 오류
				flag = 1;
			}else if(result == 1){
				// 정상
				flag = 0;
				// 실제 파일을 지워줘!
				if(filename != null){
					File file = new File("C:/Java/java/jsp-workspace/PdsModel1Ex01/WebContent/upload/" + filename);
					file.delete();
				}
			}
		}catch(SQLException e){
			System.out.println("[에러] : "+e.getMessage());
		}finally{
			if(pstmt != null) try{pstmt.close();} catch(SQLException e) {}
			if(conn != null) try{conn.close();} catch(SQLException e) {}
		}
		return flag;
	}
	
	// modify
	public BoardTO boardModify(BoardTO to) {
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		try{
			conn = dataSource.getConnection();
			
			String sql = "select subject, writer, content, mail, filename from pds_board1 where seq=?";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, to.getSeq());
			
			rs = pstmt.executeQuery();
			// 하나만 가져오니까 if문 사용
			if(rs.next()){
				to.setSubject(rs.getString("subject"));
				to.setWriter(rs.getString("writer"));
				to.setMail(rs.getString("mail"));
				to.setContent(rs.getString("content"));
				to.setFilename( rs.getString("filename"));
			}
		}catch(SQLException e){
			System.out.println("[에러] : "+e.getMessage());
		}finally{
			if(rs != null) try{rs.close();} catch(SQLException e) {}
			if(pstmt != null) try{pstmt.close();} catch(SQLException e) {}
			if(conn != null) try{conn.close();} catch(SQLException e) {}
		}
		return to;
	}
	
	
	// modify_ok
	public int boardModifyOk(BoardTO to) {
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		// 정상처리 / 비정상 => 결과를 통합처리하기 위한 변수
		int flag = 2;
		
		try{
			conn = dataSource.getConnection();
			
			String sql = "select filename from pds_board1 where seq=?";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, to.getSeq());
			
			rs = pstmt.executeQuery();
			String oldFilename = null;
			if(rs.next()){
				oldFilename = rs.getString("filename");
			}
			
			
			if(to.getFilename() != null ){
				// 새 업로드 파일이 있을 때 
				sql = "update pds_board1 set subject = ?, mail=?, content=?, filename=?, filesize=? where seq=? and password=?";
				pstmt = conn.prepareStatement(sql);
				pstmt.setString(1, to.getSubject());
				pstmt.setString(2, to.getMail());
				pstmt.setString(3, to.getContent());
				pstmt.setString(4, to.getFilename());
				pstmt.setLong(5, to.getFilesize());
				pstmt.setString(6, to.getSeq());
				pstmt.setString(7, to.getPassword());
			}else{
			
				sql = "update board1 set subject = ?, mail=?, content=? where seq=? and password=?";
				pstmt = conn.prepareStatement(sql);
				pstmt.setString(1, to.getSubject());
				pstmt.setString(2, to.getMail());
				pstmt.setString(3, to.getContent());
				pstmt.setString(4, to.getSeq());
				pstmt.setString(5, to.getPassword());
			}
			
			int result = pstmt.executeUpdate();
			if(result == 0){
				// 비밀번호 오류
				flag = 1;
			}else if(result == 1){
				// 정상
				flag = 0;
				if(to.getFilename() != null && oldFilename != null){
					File file = new File("C:/Java/java/jsp-workspace/PdsModel1Ex01/WebContent/upload/" + oldFilename);
					file.delete();
				}
			}
		}catch(SQLException e){
			System.out.println("[에러] : "+e.getMessage());
		}finally{
			if(pstmt != null) try{pstmt.close();} catch(SQLException e) {}
			if(conn != null) try{conn.close();} catch(SQLException e) {}
		}
		return flag;
	}
}

 

2) 나머지 수정은 기존 MODEL1 게시판 만들기와 비슷하다.

 

 

 

 

 

 

 

 

 

답변 글이 달리는 게시판


여러개의 알고리즘이 있지만 쉬운걸로 배워본다.

 

  • 모글     :   board_write1.jsp로 만들어짐
  • 답변글  :   board_view1.jsp 에서 board1_reply1.jsp로 만들어짐

 

컬럼 4개를 사용해서 표현한다.

 

1. 글번호           :  seq    - 순서값, 순차증가 

                                board_write1.jsp   자동

                                board_reply1.jsp   자동

2. 글그룹           :  grp    - 순서값, 모글seq   

                                board_write1.jsp   모글의 seq

                                board_reply1.jsp   모글의 seq

3. 그룹내 순서    :  grps   - 같은 그룹내의 순서   

                                board_write1.jsp     0

                                board_reply1.jsp   

                                           같은 grp내에서 (같은 layer에서 등록한지 오래될수록 숫자큼)

                                            1. 부모글의 grps 보다 큰 grps번호는 무조건 1씩 증가

                                            2. 자신은 부모글의 grps+1

4. 그룹내 깊이    :  grpl   - 같은 그룹내의 깊이     

                                board_write1.jsp     0

                                board_reply1.jsp   모글의 seq

                                           같은 grp내에서

                                           자신은 부모글의 grpl+1

 

 

 

정렬  order by grp desc, grps asc

알고리즘을 보면

 같은 layer의 글들은 최근 글이 가장 위로 올라간다.

답글에 답글이 달리게 되면 해당 모답글보다 오래된 즉 grps가 큰  것들을 전부 1씩 증가 시킨다. 

그러면 모답글보다 1 큰 grps값이 비어있게된다. 그 곳에 모답글의 답글이 들어간다.

 

 

 

 

페이징 있는 게시판에서 만든다.

 

1. 만드는 순서

 

1) 테이블 만들기

 

2) board_write1_ok.jsp 수정

write는 건드릴게 없고 write_ok가 sql문이 테이블 명이바뀌고 grp, grps, grpl 값이 들어감.

grp는 last_insert_id()+1로  insert함 (last_insert_id 함수는 테이블의 마지막 auto_increment 값을 리턴한다.)

String sql = "insert rep_board1 values(0, last_insert_id()+1, 0, 0, ?, ?, ?, ?, ?, 0, ?, now())";

 

3) list의  sql문에 테이블명, order by 바꿔줌

String sql = "select seq, subject, writer, date_format(wdate,'%Y-%m-%d') wdate, hit, datediff(now(), wdate) wgap from rep_board1 order by grp desc, grps asc";

 

4) view에서 '쓰기' 버튼을 아래 두줄로 변경

<input type="button" value="새글쓰기" class="btn_write btn_txt01" style="cursor: pointer;" onclick="location.href='board_write1.jsp?cpage=<%=cpage %>'" />
<input type="button" value="답글쓰기" class="btn_write btn_txt01" style="cursor: pointer;" onclick="location.href='board_reply1.jsp?cpage=<%=cpage %>&seq=<%=seq %>'" />

 

5) board_reply1.jsp 만들기

답글쓰기 페이지 만들기 (기존 write와 같음)

board_write1.jsp 랑 board_write1_ok.jsp 복사해서 board_reply1.jsp 랑 board_reply1_ok.jsp 를 만든다.

String seq = request.getParameter("seq");

추가하고 form 태그를 수정한다음 form 태그 밑에 아래 코드 추가.

<input type="hidden" name="cpage" value=<%=cpage %> />
input type="hidden" name="seq" value=<%=seq %> />

'쓰기' 버튼 '답글쓰기' 로 value값 변경하기.

 

6) board_reply1_ok.jsp

부모글의 grp, grps, grpl 정보 select문으로 가져와서 

답글 알고리즘 작성하기

 

가장 먼저 부모글의 grp, grps, grpl 정보를 가져온다.

// 부모글의  grp, grps, grpl 정보 가져오기
String sql = "select grp, grps, grpl from rep_board1 where seq=?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, seq);

rs = pstmt.executeQuery();
int grp = 0; 
int grps = 0; 
int grpl = 0;
if(rs.next()){
    grp = rs.getInt("grp");
    grps = rs.getInt("grps");
    grpl = rs.getInt("grpl");
}

 

다음으로,  같은 grp에서 부모글의 grps보다 큰 grps 번호는 무조건 1씩 증가시킨다.

// 같은 grp에서 부모글의 grps 보다 큰 grps번호는 무조건 1씩 증가
sql = "update rep_board1 set grps=grps+1 where grp=? and grps>?";
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, grp);
pstmt.setInt(2, grps);

pstmt.executeQuery();

 

그 다음,  insert문을 다음과 같이 작성한다.

sql = "insert rep_board1 values(0, ?, ?, ?, ?, ?, ?, ?, ?, 0, ?, now())";
pstmt = conn.prepareStatement(sql);

pstmt.setInt(1, grp);
pstmt.setInt(2, grps+1);
pstmt.setInt(3, grpl+1);

pstmt.setString(4, subject);
pstmt.setString(5, writer);
pstmt.setString(6, mail);
pstmt.setString(7, password);
pstmt.setString(8, content);
pstmt.setString(9, wip);

grps와 grpl은 항상 부모보다 +1 증가하므로 항상 grps+1, grpl+1 이라는 점을 기억하자!

 

 

그 다음, 답글쓰기에 성공했을 때 아래와 같이 cpage 값을 함께 넘겨 준다. (paging이 있는 게시판이므로)

out.println("location.href='board_list1.jsp?cpage="+ cpage +"';");

 

 

board_reply1_ok.jsp 전체 코드

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<%@ page import="javax.naming.Context" %>
<%@ page import="javax.naming.InitialContext" %>
<%@ page import="javax.naming.NamingException" %>
<%@ page import="javax.sql.DataSource" %>

<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.PreparedStatement" %>
<%@ page import="java.sql.ResultSet" %>
<%@ page import="java.sql.SQLException" %>

<%
	request.setCharacterEncoding("utf-8");

	String cpage = request.getParameter("cpage");
	String seq = request.getParameter("seq");

	String subject = request.getParameter("subject");
	String writer = request.getParameter("writer");
	// 필수 입력 항목이 아닌 경우
	String mail = "";
	if(!request.getParameter("mail1").equals("") && !request.getParameter("mail2").equals("")){
		mail = request.getParameter("mail1") + "@" + request.getParameter("mail2");
	}
	String password = request.getParameter("password");
	String content = request.getParameter("content");
	
	String wip = request.getRemoteAddr();
	
	Connection conn = null;
	PreparedStatement pstmt = null;
	ResultSet rs = null;
	
	// 정상처리 / 비정상 => 결과를 통합처리하기 위한 변수
	int flag = 1;
	
	try{
		
		Context iniCtx = new InitialContext();
		Context envCtx = (Context)iniCtx.lookup("java:comp/env");
		DataSource dataSource = (DataSource)envCtx.lookup("jdbc/mariadb2");
	
		conn = dataSource.getConnection();
		
		// 부모글의  grp, grps, grpl 정보 가져오기
		String sql = "select grp, grps, grpl from rep_board1 where seq=?";
		pstmt = conn.prepareStatement(sql);
		pstmt.setString(1, seq);
		
		rs = pstmt.executeQuery();
		int grp = 0; 
		int grps = 0; 
		int grpl = 0;
		if(rs.next()){
			grp = rs.getInt("grp");
			grps = rs.getInt("grps");
			grpl = rs.getInt("grpl");
		}
		
		// 같은 grp에서 부모글의 grps 보다 큰 grps번호는 무조건 1씩 증가
		sql = "update rep_board1 set grps=grps+1 where grp=? and grps>?";
		pstmt = conn.prepareStatement(sql);
		pstmt.setInt(1, grp);
		pstmt.setInt(2, grps);
		
		pstmt.executeQuery();
		
		
		sql = "insert rep_board1 values(0, ?, ?, ?, ?, ?, ?, ?, ?, 0, ?, now())";
		pstmt = conn.prepareStatement(sql);
		
		pstmt.setInt(1, grp);
		pstmt.setInt(2, grps+1);
		pstmt.setInt(3, grpl+1);
		
		pstmt.setString(4, subject);
		pstmt.setString(5, writer);
		pstmt.setString(6, mail);
		pstmt.setString(7, password);
		pstmt.setString(8, content);
		pstmt.setString(9, wip);
		
		// 일반적으로 0 값은 정상이다.
		int result = pstmt.executeUpdate();
		if(result == 1){
			flag = 0;
		}
	}catch(NamingException e){
		System.out.println("[에러] : "+e.getMessage());
	}catch(SQLException e){
		System.out.println("[에러] : "+e.getMessage());
	}finally{
		if(pstmt != null) pstmt.close();
		if(conn != null) conn.close();
	}
	
	out.println("<script type='text/javascript'>");
	if(flag == 0){
		out.println("alert('답글쓰기에 성공했습니다.');");
		out.println("location.href='board_list1.jsp?cpage="+ cpage +"';");
	}else{
		out.println("alert('답글쓰기에 실패했습니다.');");
		out.println("history.back();");
	}
	out.println("</script>");
	

%>

 

 

 

7) list에서 답글은 답글처럼 보이게 하기

다음과 같이 for문을 수정한다.

for(int i=0; i<recordPerPage && rs.next(); i++){
    String seq = rs.getString("seq");

    int grpl = rs.getInt("grpl");
    String sgrpl = "";
    // 더아래 layer일수록 더 들여쓰기 되게
    for(int j=1; j<grpl; j++){
        sgrpl += "&nbsp;&nbsp;&nbsp;&nbsp;";
    }

    String subject = rs.getString("subject");
    String writer = rs.getString("writer");
    String wdate = rs.getString("wdate");
    String hit = rs.getString("hit");
    int wgap = rs.getInt("wgap");

    sbHtml.append("<tr>");
    sbHtml.append("		<td>&nbsp;</td>");
    sbHtml.append("		<td>"+ seq +"</td>");
    sbHtml.append("		<td class='left'>");

    // 답글이면 sgrpl로 들여쓰기하고 답글표시 img 추가
    if(grpl != 0){
        sbHtml.append(sgrpl + "<img src='../../images/icon_re1.gif' />");
    }

    sbHtml.append(			"<a href='board_view1.jsp?cpage="+ cpage +"&seq=" + seq + "'> "+ subject + "</a>&nbsp;");
    if(wgap == 0){
        sbHtml.append(			"<img src='../../images/icon_hot.gif' alt='HOT'></td>");
    }
    sbHtml.append("		<td>"+ writer +"</td>");
    sbHtml.append("		<td>"+ wdate +"</td>");
    sbHtml.append("		<td>"+ hit +"</td>");
    sbHtml.append("		<td>&nbsp;</td>");
    sbHtml.append("</tr>");
}

 

board_list1.jsp 전체 코드

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
	
<%@ page import="javax.naming.Context" %>
<%@ page import="javax.naming.InitialContext" %>
<%@ page import="javax.naming.NamingException" %>
<%@ page import="javax.sql.DataSource" %>

<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.PreparedStatement" %>
<%@ page import="java.sql.ResultSet" %>
<%@ page import="java.sql.SQLException" %>

<%@ page import="java.util.Calendar" %>

<%
	request.setCharacterEncoding("utf-8");
	
	// cpage값이 없으면 1로 셋 하고 아니면 해당 페이지로 넘어가라
	int cpage = 1;
	if(request.getParameter("cpage") != null && !request.getParameter("cpage").equals("")){
		cpage = Integer.parseInt(request.getParameter("cpage"));
	}
	
	int recordPerPage = 10;
	int totalRecord = 0;
	
	// 전체 페이지 갯수 (0이 될수 없음)
	int totalPage = 1;
	
	int blockPerPage = 5;
	
	Connection conn = null;
	PreparedStatement pstmt = null;
	ResultSet rs = null;

	
	StringBuffer sbHtml = new StringBuffer();
	try{
		
		Context iniCtx = new InitialContext();
		Context envCtx = (Context)iniCtx.lookup("java:comp/env");
		DataSource dataSource = (DataSource)envCtx.lookup("jdbc/mariadb2");
	
		conn = dataSource.getConnection();
		
		String sql = "select seq, grpl, subject, writer, date_format(wdate,'%Y-%m-%d') wdate, hit, datediff(now(), wdate) wgap from rep_board1 order by grp desc, grps asc";
		pstmt = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
		
		rs = pstmt.executeQuery();
		
		// 읽을 위치를 맨 아래로
		rs.last();
		// 전체 데이터 갯수
		totalRecord = rs.getRow();
		rs.beforeFirst();
		
		// 읽을 위치 지정
		int skip = (cpage-1) * recordPerPage;
		if(skip != 0) rs.absolute(skip);
		
		totalPage = ((totalRecord - 1) / recordPerPage + 1);
		
		// 10개 또는 마지막 데이터까지
		for(int i=0; i<recordPerPage && rs.next(); i++){
			String seq = rs.getString("seq");
			
			int grpl = rs.getInt("grpl");
			String sgrpl = "";
			// 더아래 layer일수록 더 들여쓰기 되게
			for(int j=1; j<grpl; j++){
				sgrpl += "&nbsp;&nbsp;&nbsp;&nbsp;";
			}
			
			String subject = rs.getString("subject");
			String writer = rs.getString("writer");
			String wdate = rs.getString("wdate");
			String hit = rs.getString("hit");
			int wgap = rs.getInt("wgap");
			
			sbHtml.append("<tr>");
			sbHtml.append("		<td>&nbsp;</td>");
			sbHtml.append("		<td>"+ seq +"</td>");
			sbHtml.append("		<td class='left'>");
			
			// 답글이면 sgrpl로 들여쓰기하고 답글표시 img 추가
			if(grpl != 0){
				sbHtml.append(sgrpl + "<img src='../../images/icon_re1.gif' />");
			}
			
			sbHtml.append(			"<a href='board_view1.jsp?cpage="+ cpage +"&seq=" + seq + "'> "+ subject + "</a>&nbsp;");
			if(wgap == 0){
				sbHtml.append(			"<img src='../../images/icon_hot.gif' alt='HOT'></td>");
			}
			sbHtml.append("		<td>"+ writer +"</td>");
			sbHtml.append("		<td>"+ wdate +"</td>");
			sbHtml.append("		<td>"+ hit +"</td>");
			sbHtml.append("		<td>&nbsp;</td>");
			sbHtml.append("</tr>");
		}
	}catch(NamingException e){
		System.out.println("[에러] : "+e.getMessage());
	}catch(SQLException e){
		System.out.println("[에러] : "+e.getMessage());
	}finally{
		if(rs != null) rs.close();
		if(pstmt != null) pstmt.close();
		if(conn != null) conn.close();
	}
%>
	
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Insert title here</title>
<link rel="stylesheet" type="text/css" href="../../css/board_list.css">
</head>

<body>
<!-- 상단 디자인 -->
<div class="con_title">
	<h3>게시판</h3>
	<p>HOME &gt; 게시판 &gt; <strong>게시판</strong></p>
</div>
<div class="con_txt">
	<div class="contents_sub">
		<div class="board_top">
			<div class="bold">총 <span class="txt_orange">1</span>건</div>
		</div>

		<!--게시판-->
		<div class="board">
			<table>
			<tr>
				<th width="3%">&nbsp;</th>
				<th width="5%">번호</th>
				<th>제목</th>
				<th width="10%">글쓴이</th>
				<th width="17%">등록일</th>
				<th width="5%">조회</th>
				<th width="3%">&nbsp;</th>
			</tr>
			<%=sbHtml %>
			</table>
		</div>	
		<!--//게시판-->

		<div class="align_right">
			<input type="button" value="쓰기" class="btn_write btn_txt01" style="cursor: pointer;" onclick="location.href='board_write1.jsp?cpage=<%=cpage %>'" />
		</div>
		
		<!--페이지넘버-->
		<div class="paginate_regular">
			<div align="absmiddle">
			<%
				// << , >> 를 위해 페이지 블럭 시작(startBlock), 끝(endBlock) 페이지 정의
				int startBlock = ((cpage - 1) / blockPerPage) * blockPerPage +1;
				int endBlock = ((cpage - 1) / blockPerPage) * blockPerPage + blockPerPage;
				if(endBlock >= totalPage){
					endBlock = totalPage;
				}
				
				// << 구현
				if(startBlock == 1){
					out.println("<span>&lt;&lt;</span>");
				}else{
					out.println("<span><a href='board_list1.jsp?cpage="+ (startBlock - blockPerPage) +"'>&lt;&lt;</a></span>");
				}
				out.println("&nbsp;");
			
				if(cpage == 1){
					out.println("<span><a>&lt;</a></span>");
				}else{
					out.println("<span><a href='board_list1.jsp?cpage="+ (cpage-1) +"'>&lt;</a></span>");
				}
				out.println("&nbsp;&nbsp;");
			
				for(int i=startBlock; i<=endBlock; i++){
					if(i == cpage){
						// 현재 페이지
						out.println("<span>[" + i + "]</span>");
					}else{
						out.println("<span><a href='board_list1.jsp?cpage="+ i +"'>"+ i + "</a></span>");
					}
				}
				
				out.println("&nbsp;&nbsp;");
				if(cpage == totalPage){
					out.println("<span><a>&gt;</a></span>");
				}else{
					out.println("<span><a href='board_list1.jsp?cpage="+ (cpage+1) +"'>&gt;</a></span>");
				}
					
				// >> 구현
				out.println("&nbsp;");
				if(endBlock == totalPage){
					out.println("<span>&gt;&gt;</span>");
				}else{
					out.println("<span><a href='board_list1.jsp?cpage="+ (startBlock + blockPerPage) +"'>&gt;&gt;</a></span>");
				}
			%>
			</div>
		</div>
		<!--//페이지넘버-->
		
	</div>
</div>
<!--//하단 디자인 -->

</body>
</html>

 

 

 

이 게시판의 문제는???????

답변글이 삭제되면 list에서 아예 없어지면 안된다. 

그 공간을 남겨놔야한다. 

delete를 하면 delete가 안되고 update가 되면서 view로 가야한다. 

 

 

 

 

 

 

이클립스 말고 톰캣을 돌려서 게시판 실행시키기 ( 배포 )


p351

서버를 이용해서 웹 어플리케이션 실행하기 

p357

배포할 WAR 파일 생성하기 

 

개발 서버에 배포(deployment)

https://localhost:8081/

          => C:\Java\apache-tomcat-9.0.41\webapps\ROOT

 

C:\Java\apache-tomcat-9.0.41\webapps\

          board(프로젝트)

                    META-INF

                             context.xml

                    WEB-INF

                             lib

                                       *.jar

                             classes

                                       *.class

                             *.jsp

=> https://localhost:8081/board/*.jsp  

 

 

 

 

1. 이클립스에서 실행중인 tomcat을 끄기

 

2. 이클립스 끄기

 

3. 탐색기에서 다음을 실행시키기

C:\Java\apache-tomcat-9.0.41\bin\startup.bat

 

4. 브라우저에서 localhost:8081로 접속 

     -> 톰캣 화면 나옴

 

5. C:\Java\apache-tomcat-9.0.41\webapps에 board폴더만들고

board 폴더 안에 아래와 같이 만듬

index.jsp 를 메모장에서 열어서 jsp코드 작성하고 

https://localhost:8081/board/index.jsp 에서 실행시키면 실행됨

 

 

6. 5번의 board폴더를 이클립스의 프로젝트라고 치고 파일 복사함

 

7. tomcat 껐다 켜고 브라우저에서 실행시키기

https://localhost:8081/board/mariadb/simple1/board_list1.jsp

 

8. model1인 경우 

classes폴더 복사해서 WEB-INF 폴더 안에 붙여넣기

jsp파일폴더인 model1은 위와 동일하기 붙여넣기

https://localhost:8081/board/mariadb/model1/board_list1.jsp

 


 

이렇게 파일 하나하나 복사해도 되고 

프로젝트 하나를 그냥 압축해와서 해도 된다. 

 

 war(Web Archiver) - 압축파일

 *.war 로 해놓으면 지가 알아서 실행 

이클립스로 만드는게 편함

 

이클립스에서 Model1Ex02 프로젝트를 war파일로 만든다.

 

만들고 board 폴더 안에 넣으면 자동으로 풀어진다.

톰캣 껐다가 켜고 경로

https://localhost:8081/Model1Ex02/mariadb/emoticon1/board_list1.jsp

위에서 하던 대로 하면 된다.

728x90
반응형