일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- NIO
- deque
- string
- GC로그수집
- union_find
- Java
- Calendar
- set
- 큐
- 힙덤프
- html
- 리소스모니터링
- BFS
- map
- spring boot
- priority_queue
- 스프링부트
- dfs
- CSS
- javascript
- Properties
- 스택
- sql
- scanner
- date
- JPA
- alter
- math
- Union-find
- List
- Today
- Total
매일 조금씩
12/30 - JSP(8) : 파일 첨부 되는 model1 게시판 만들기, 톰캣만으로 게시판 실행(배포) 본문
12/30 - JSP(8) : 파일 첨부 되는 model1 게시판 만들기, 톰캣만으로 게시판 실행(배포)
mezo 2021. 1. 4. 20:02model1
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 += " ";
}
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> </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> ");
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> </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 += " ";
}
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> </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> ");
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> </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 > 게시판 > <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%"> </th>
<th width="5%">번호</th>
<th>제목</th>
<th width="10%">글쓴이</th>
<th width="17%">등록일</th>
<th width="5%">조회</th>
<th width="3%"> </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><<</span>");
}else{
out.println("<span><a href='board_list1.jsp?cpage="+ (startBlock - blockPerPage) +"'><<</a></span>");
}
out.println(" ");
if(cpage == 1){
out.println("<span><a><</a></span>");
}else{
out.println("<span><a href='board_list1.jsp?cpage="+ (cpage-1) +"'><</a></span>");
}
out.println(" ");
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(" ");
if(cpage == totalPage){
out.println("<span><a>></a></span>");
}else{
out.println("<span><a href='board_list1.jsp?cpage="+ (cpage+1) +"'>></a></span>");
}
// >> 구현
out.println(" ");
if(endBlock == totalPage){
out.println("<span>>></span>");
}else{
out.println("<span><a href='board_list1.jsp?cpage="+ (startBlock + blockPerPage) +"'>>></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
위에서 하던 대로 하면 된다.
'빅데이터 플랫폼 구축을 위한 자바 개발자 양성과정' 카테고리의 다른 글
01/05 - JSP(10) : 기본객체 영역, 쿠키, 세션, 서블릿 클래스란? (0) | 2021.01.16 |
---|---|
12/31 - JSP(9) - 이전글, 다음글 있는 model1 게시판 만들기 (0) | 2021.01.10 |
12/29 - JSP(7) : 파일첨부 방법, 파일첨부 되는 model1 게시판 만들기(기본 게시판) (1) | 2021.01.04 |
12/28 - JSP(6) : JSP 기본객체, model1기법으로 게시판 만들기 (0) | 2021.01.04 |
12/24 - JSP(5) : 최신글 표시, 페이징 있는 게시판 만들기 (0) | 2021.01.04 |