중요 정보
jsp에서는 백틱(`)의 ${}이 el태그로 인식한다 그걸을 인식하지않기위해 설정해야한다
더보기
<%@ page isELIgnored="true" %>
페이징 처리
해당 게시판을 출력해주는 함수는 별개의 함수로 설정해주며
새로운 페이지 실행 시나 페이지가 변경 시 계속 사용하도록한다
jsp로 sp, ep, tp, data(페이지에 표시할 데이터 arr)를 json형태로 만들어주며
이후 js에서 출력해주며 jsp에서 버튼 이벤트를한 뒤 메서드를 다시 실행시켜 게시판이 변경되도록한다
페이징 처리 함수
더보기
const pageList = (sp, ep, tp) => {
let pageCode = `<ul class="pagination" style="margin : 10px auto">`;
// 이전버튼 출력 id=prev
if(sp>1){
pageCode +=`<li class="page-item"><a id="prev" class="page-link" href="#">Previous</a></li>`;
}
// 페이지 버튼 출력 클래스 이름 .pageno
for(var i=sp; i<=ep; i++){
if(currentPage==i){
pageCode+=`<li class="page-item active"><a class="page-link pageno" href="#">${i}</a></li>`;
} else{
pageCode+=`<li class="page-item"><a class="page-link pageno" href="#">${i}</a></li>`;
}
}
// 다음버튼 출력 id=next
if(ep < tp){
pageCode+=`<li class="page-item"><a id="next" class="page-link" href="#">Next</a></li>`;
}
pageCode+= `</ul>`;
return pageCode;
}
초기설정
더보기
create table boardtab (
num number not null primary key,
subject varchar2(50) not null,
writer varchar2(15) not null,
mail varchar2(30),
password varchar2(10) not null,
content varchar2(2000),
hit number not null,
wip char(15) not null,
wdate date not null
);
create table replytab( -- 댓글
renum number not null primary key,
bonum number not null,
name varchar2(15) not null,
cont varchar2(1000) not null,
redate date not null,
CONSTRAINT REPLY_BONUM FOREIGN KEY(BONUM)
REFERENCES BOARDTAB(NUM)
ON DELETE CASCADE
);
--시퀀스 생성
create sequence boardtab_num_seq nocache;
create sequence replytab_renum_seq nocache;
-- insert
insert into boardtab values (boardtab_num_seq.nextval, '김제목1', '김은대', 'test1@test.com', '1234', '내용1', 0, '000.000.000.000', sysdate);
insert into boardtab values (boardtab_num_seq.nextval, '이제목2', '이쁜이', 'test2@test.com', '1234', '내용2', 0, '000.000.000.000', sysdate);
insert into boardtab values (boardtab_num_seq.nextval, '성제목3', '이쁜이', 'test3@test.com', '1234', '내용3', 0, '000.000.000.000', sysdate);
insert into boardtab values (boardtab_num_seq.nextval, '김제목4', '성윤미', 'test4@test.com', '1234', '내용4', 0, '000.000.000.000', sysdate);
insert into boardtab values (boardtab_num_seq.nextval, '이제목5', '김은대', 'test5@test.com', '1234', '내용5', 0, '000.000.000.000', sysdate);
insert into boardtab values (boardtab_num_seq.nextval, '김제목6', '신영남', 'test6@test.com', '1234', '내용6', 0, '000.000.000.000', sysdate);
insert into boardtab values (boardtab_num_seq.nextval, '이제목7', '김은대', 'test7@test.com', '1234', '내용7', 0, '000.000.000.000', sysdate);
insert into boardtab values (boardtab_num_seq.nextval, '신제목8', '김은대', 'test8@test.com', '1234', '내용8', 0, '000.000.000.000', sysdate);
insert into boardtab values (boardtab_num_seq.nextval, '신제목9', '이쁜이', 'test9@test.com', '1234', '내용9', 0, '000.000.000.000', sysdate);
insert into boardtab values (boardtab_num_seq.nextval, '김제목10', '이쁜이', 'test10@test.com', '1234', '내용10', 0, '000.000.000.000', sysdate);
insert into boardtab values (boardtab_num_seq.nextval, '김제목11', '신용환', 'test11@test.com', '1234', '내용11', 0, '000.000.000.000', sysdate);
insert into boardtab values (boardtab_num_seq.nextval, '이제목12', '이쁜이', 'test12@test.com', '1234', '내용12', 0, '000.000.000.000', sysdate);
insert into boardtab values (boardtab_num_seq.nextval, '이제목13', '성윤미', 'test13@test.com', '1234', '내용13', 0, '000.000.000.000', sysdate);
insert into boardtab values (boardtab_num_seq.nextval, '성제목14', '성윤미', 'test14@test.com', '1234', '내용14', 0, '000.000.000.000', sysdate);
insert into boardtab values (boardtab_num_seq.nextval, '신제목15', '김은대', 'test15@test.com', '1234', '내용15', 0, '000.000.000.000', sysdate);
insert into boardtab values (boardtab_num_seq.nextval, '신제목16', '이쁜이', 'test16@test.com', '1234', '내용16', 0, '000.000.000.000', sysdate);
insert into boardtab values (boardtab_num_seq.nextval, '김제목17', '이쁜이', 'test17@test.com', '1234', '내용17', 0, '000.000.000.000', sysdate);
insert into boardtab values (boardtab_num_seq.nextval, '김제목18', '신용환', 'test18@test.com', '1234', '내용18', 0, '000.000.000.000', sysdate);
insert into boardtab values (boardtab_num_seq.nextval, '이제목19', '김은대', 'test19@test.com', '1234', '내용19', 0, '000.000.000.000', sysdate);
insert into boardtab values (boardtab_num_seq.nextval, '김제목20', '김은대', 'test20@test.com', '1234', '내용20', 0, '000.000.000.000', sysdate);
commit;
★★ js ★★
board, reply관리에 관련된 메서드를 저장하는 공간
// board 게시판 출력
function listPerPage(){
// 검색 대비
let vtype = $('#stype option:selected').val();
let vword = $('#sword').val().trim();
// 서버전송
$.ajax({
url : `${propath}/BoardList.do`,
type : "POST",
data : JSON.stringify({
page : currentPage,
stype : vtype,
sword : vword
}),
content : "application/json; charset=utf-8",
success : function(data){
// console.log(data);
// 게시판 출력 처리
let code = `<div class="container mt-3">
<div id="accordion">`;
// content는 /n를 <br>로 replace해야된다
$.each(data.datas, function(i, v){
code += `<div class="card">
<div class="card-header">
<a idx="${this.num}" name="title" class="btn action" data-bs-toggle="collapse" href="#collapse${this.num}"> ${this.subject} </a>
</div>
<div id="collapse${this.num}" class="collapse" data-bs-parent="#accordion">
<div class="card-body">
<div class="p12">
<p class="p1">
작성자:<span class="wr">${this.writer}</span>
이메일:<span class="em">${this.mail}</span>
조회수:<span class="hi">${this.hit}</span>
날짜:<span class="da">${this.wdate}</span>
</p>
<p class="p2">`;
if(uvo!=null&&this.writer==uvo.mem_name){
code+=`<input type="button" value="수정" name="modify" class="action" idx="${this.num}">
<input type="button" value="삭제" name="delete" class="action" idx="${this.num}">`;
}
code+=`</p>
</div>
<p class="p3">
${this.content.replace(/\n/g,"<br>")}
</p>
<p class="p4">
<textarea rows="" cols="60"></textarea>
<input type="button" value="등록" name="reply" class="action" idx="${this.num}">
</p>
</div>
</div>
</div>`;
})
code += `</div></div>`
$('#boardList').html(code);
// 페이지 번호 처리
// sp, ep, tp
let pageCode = pageList(data.sp, data.ep, data.tp);
$('#pageList').html(pageCode);
},
error : function(xhr){
alert("오류 코드 : "+xhr.status);
},
dataType : 'json'
})
}
// 게시판 번호 출력
const pageList = (sp, ep, tp) => {
let pageCode = `<ul class="pagination" style="margin : 10px auto">`;
// 이전버튼 출력
if(sp>1){
pageCode +=`<li class="page-item"><a id="prev" class="page-link" href="#">Previous</a></li>`;
}
// 페이지 버튼 출력
for(var i=sp; i<=ep; i++){
if(currentPage==i){
pageCode+=`<li class="page-item active"><a class="page-link pageno" href="#">${i}</a></li>`;
} else{
pageCode+=`<li class="page-item"><a class="page-link pageno" href="#">${i}</a></li>`;
}
}
// 다음버튼 출력
if(ep < tp){
pageCode+=`<li class="page-item"><a id="next" class="page-link" href="#">Next</a></li>`;
}
pageCode+= `</ul>`;
return pageCode;
}
// 게시판 추가
const insert = () =>{
/* $.ajax({
url : `${propath}/BoardInsert.do`,
type : "POST",
data : JSON.stringify(fdata),
content : "application/json; charset=utf-8",
success : function(data){
if(data.flag==1){
alert("글이 작성되었습니다")
}
},
error : function(xhr){
alert("오류 코드 : "+xhr.status);
},
dataType : 'json'
})*/
// 단축메뉴 value값만 씀
/* $.post(
`${propath}/BoardInsert.do`, // url
JSON.stringify(fdata), // data
function(data){ //success
if(data.flag==1){
alert("글이 작성되었습니다")
}
console.log(data);
},
'json' //dataType
)*/
fetch(`${propath}/BoardInsert.do`,{
method : "POST",
hearders : {
"Content-type" : "application/json;charset=utf-8" // json 직렬화
},
body : JSON.stringify(fdata)
})
.then(function(response){
console.log("response", response);
if(!response.ok){
throw new Error(`오류발생 : ${response.status}`);
}
return response.json(); // 결과를json로 받음
})
.then(function(data){
if(data.flag==1){
alert("글이 작성되었습니다")
}
currentPage = 1;
listPerPage();
})
}
// 게시판 변경
const boardUpdate = () =>{
$.ajax({
url : `${propath}/boardUpdate.do`,
type : "POST",
data : JSON.stringify(fdata),
content : "application/json; charset=utf-8",
success : function(data){
console.log(data.flag)
if(data.flag=="success"){
let ta = dthis.parents('.card');
ta.find('.btn').text(fdata.subject)
ta.find('.em').text(fdata.mail)
ta.find('.p3').html(fdata.content.replace(/\n/g, "<br>"));
}
},
error : function(xhr){
alert("오류 코드 : "+xhr.status);
},
dataType : 'json'
})
}
function updateReply(){
}
// 조회수 증가
function updateHit(){
$.ajax({
url : `${propath}/updateHit.do`,
type : "GET",
/* contentType : 기본값 생략가능*/
data : {num : vbonum},
success : function(data){
if(data.flag=="success"){
// 화면만 수정
let hitNo = parseInt(dthis.parents('.card').find('.hi').text())+1;
dthis.parents('.card').find('.hi').text(hitNo);
}
},
error : function(xhr){
alert("오류 코드 : "+xhr.status);
},
dataType : 'json'
})
}
// 게시판 삭제
function deleteBoard(){
$.ajax({
url : `${propath}/boardDelete.do`,
type : "GET",
/* contentType : 기본값 생략가능*/
data : {num : vbonum},
success : function(data){
if(data.flag=="success"){
console.log(data.flag);
currentPage = 1;
location.href = `${propath}/board/board.jsp`;
}
},
error : function(xhr){
alert("오류 코드 : "+xhr.status);
},
dataType : 'json'
})
}
// 댓글 추가
// .card-body밑에 댓글 내용 추가
function replyWrite(){
$.ajax({
url : `${propath}/ReplyWrite.do`,
type : "POST",
data : JSON.stringify(reply),
content : "application/json; charset=utf-8",
success : function(data){
if(data.flag==1){
alert("글이 작성되었습니다")
}
replyList()
},
error : function(xhr){
alert("오류 코드 : "+xhr.status);
},
dataType : 'json'
})
}
// 댓글 출력
function replyList(){
$.ajax({
url : `${propath}/replyList.do`,
type : "POST",
/* contentType : 기본값 생략가능*/
data : `bonum=${vbonum}`,
success : function(data){
let rcode = `<div id="reply">`;
$.each(data, function(i, v){
rcode += `<div class="reply-body" idx="${this.renum}">
<div class="p12">
<p class="p1">
작성자:<span class="rwr">${this.name}</span>
날짜:<span class="rda">${this.redate}</span>
</p>
<p class="rp2">`;
if(uvo!=null&&this.name==uvo.mem_name){
rcode+=`<input type="button" value="댓글수정" name="r_modify" class="action" idx="${this.renum}">
<input type="button" value="댓글삭제" name="r_delete" class="action" idx="${this.renum}">`;
}
rcode+=`</p>
</div>
<p class="rp3">
${this.cont.replace(/\n/g,"<br>")}
</p>
</div>`;
})
// class ='card-body'검색
// 기존 댓글 삭제
// jsp 이벤트 핸들러 작성시 this에서 card-body를 대입받는
// gthis선언
$(gthis).find('#reply').remove();
$(gthis).append(rcode);
},
error : function(xhr){
alert("오류 코드 : "+xhr.status);
},
dataType : 'json'
})
}
// 댓글 삭제
function replyDelete(){
$.ajax({
url : `${propath}/replyDelete.do`,
type : "POST",
data : {renum : vnum},
success : function(data){
// console.log(data.flag);
dthis.parents('.reply-body').remove();
},
error : function(xhr){
alert("오류 코드 : "+xhr.status);
},
dataType : 'json'
})
}
// 댓글 수정
function replyUpdate(){
$.ajax({
url : `${propath}/replyUpdate.do`,
type : "POST",
data : {renum : vnum,
cont : ucont},
success : function(data){
console.log(data.flag);
dthis.parents('.reply-body').find('.rp2').show();
dthis.parents('.reply-body').find('.rp3').html(ucont.trim().replace(/\n/g,"<br>"));
},
error : function(xhr){
alert("오류 코드 : "+xhr.status);
},
dataType : 'json'
})
}
index.jsp
<jsp:include> 액션 태그는 페이지를 모듈화
즉 따로따로 실행 된 후 그 결과(html)만을 가지고 include 한다
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.3/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script>
<link rel="stylesheet" href="../css/logpro.css">
</head>
<body>
<%-- -. 서버측 include가 아닌 클라이언트측의 include라 생각하면 간단하다
즉 출력 결과만(html코드)을 include 한다
-. include 되는 페이지와 변수를 같이 사용할 수 없다
-. get 방식으로 파라미터를 전달 할수 없다
<jsp:include page="b.jsp" flush="true"/>
a.jsp 결과에 b.jsp 가 실행된 결과가 include 된다
flush -. true : 문서의 출력 결과를 항상 버퍼내에서 갱신 하라는 의미이다
즉 따로따로 실행 된 후 그 결과(html)만을 가지고 include 한다
<!-- <jsp:include> 액션 태그는 페이지를 모듈화할때 사용된다. -->
--%>
<header>
<div class="dlog">
<jsp:include page="/start/logpro.jsp"/>
</div>
<br>
<a href="<%= request.getContextPath() %>/비동기fetch/회원가입.html" target="iboard">회원가입</a>
<a href="<%= request.getContextPath() %>/board/test.html" target="iboard">게시판</a>
<br><br>
</header>
<section >
<iframe name="iboard" src="<%= request.getContextPath() %>/board/test.html"></iframe>
</section>
</body>
</html>
로그인 logpro.jsp
ajax
$.ajax( {
url : '경로',
type : 'get || post',
[data : JSON.stringify({}),
ContentType : "application/json;charset=utf-8",]
success : function(){ },
error : function(){ },
dataType :
})
<%@page import="kr.or.ddit.member.vo.MemberVO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page isELIgnored="true" %>
<script src="../js/jquery-3.6.4.min.js"></script>
<script>
mypath = '<%= request.getContextPath()%>';
$(function(){
/* $(document).on('click', '#logout', () => { */
$('#logout').on('click', ()=>{
$.ajax({
url : `${mypath}/LogoutPro.do`,
type : 'get',
success : function(res){
// 새로고침을 시켜줌
location.href="/boardpro/start/index.jsp";
},
error : function(xhr){
alert("상태 : " + xhr.status); //200 : json형태오류 404 : FileNotFound
},
dataType : 'html'
})
})
/* $(document).on('click', '#login', () => { */
$('#login').on('click', ()=>{
//입력한 id와 pass 값를 가져온다
idvalue = $('#id').val();
passvalue = $('#pass').val();
console.log(idvalue, passvalue);
$.ajax({
url : `${mypath}/LoginPro.do`,
type : 'post',
data : JSON.stringify({"mem_id" : idvalue , "mem_pass" : passvalue }),
ContentType : "application/json;charset=utf-8", // json 직렬화
success : function(res){
// 새로고침을 시켜줌
location.href="/boardpro/start/index.jsp";
},
error : function(xhr){
alert("상태 : " + xhr.status); //200 : json형태오류 404 : FileNotFound
},
dataType : 'html'
})
})
})
</script>
<style>
#check { color : red;}
</style>
<%
//세션 로그인 값 - 로그인 했는지 안했는지
MemberVO vo = (MemberVO)session.getAttribute("loginok");
String check = (String)session.getAttribute("check");
System.out.println("login : " + vo);
System.out.println("check : " + check);
if(vo == null){
%>
<input id="id" type="text" placeholder="id" >
<input id="pass" type="password" placeholder="password">
<button id="login" type="button">로그인</button><br>
<% }else if(vo != null ){ %>
<span><%= vo.getMem_name() %>님 환영합니다</span>
<button id="logout" type="button">로그아웃</button><br>
<% } %>
<%
if(check == "false" ){
%>
<span id="check">로그인 오류 또는 비회원입니다</span>
<%
}
%>
로그인 서블릿
package kr.or.ddit.member.controller;
import java.io.BufferedReader;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.google.gson.Gson;
import kr.or.ddit.member.service.MemberServiceImpl;
import kr.or.ddit.member.vo.MemberVO;
@WebServlet("/LoginPro.do")
public class LoginPro extends HttpServlet {
private static final long serialVersionUID = 1L;
private static MemberServiceImpl service = MemberServiceImpl.getInstance();
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
StringBuffer buf = new StringBuffer();
String line = null;
try {
BufferedReader reader = request.getReader();
while((line=reader.readLine())!=null) {
buf.append(line);
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
String reqdata = buf.toString();
Gson gson = new Gson();
MemberVO vo = gson.fromJson(reqdata, MemberVO.class);
HttpSession session = request.getSession();
MemberVO memVo = service.login(vo);
if(memVo!=null) {
session.setAttribute("loginok", memVo);
session.setAttribute("check", "true");
} else {
session.setAttribute("check", "false");
}
// view페이지(logpro.jsp)로 간다 - forward -
// html코드로 응답결과를 생성한다 - view페이지 안에 클릭이벤트도 같이 포함
// response.sendRedirect(request.getContextPath()+"/start/logpro.jsp");
request.getRequestDispatcher("/start/logpro.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
로그아웃 서블릿
package kr.or.ddit.member.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* Servlet implementation class LogoutPro
*/
@WebServlet("/LogoutPro.do")
public class LogoutPro extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
// session.invalidate();
session.removeAttribute("loginok");
session.removeAttribute("check");
// view페이지 - logpro.jsp
// 응답결과 생성 - html
// response.sendRedirect(request.getContextPath()+"/start/logpro.jsp");
request.getRequestDispatcher("/start/logpro.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
▷ board 기본설정
service에서 totalCount를 토대로 page계산을 한다
이 때, start / end는 게시판에서 rownum에서 가져올 만큼의 갯수를 뜻하며
startpage/ endpage는 게시판에 선택할 수 있는 page번호를 뜻한다
더보기
config
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org/DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- DB연결 정보가 있는 Properties파일 설정 -->
<properties resource="kr/or/ddit/mybatis/config/dbinfo.properties" />
<!-- MyBatis의 기본 설정값 세팅 -->
<settings>
<!-- 데이터가 null로 전달되었으면 빈칸으로 인지되지 않고 null로 인식하는 설정 -->
<!-- value값은 전부 대문자 -->
<setting name="jdbcTypeForNull" value="NULL"/>
<setting name="logImpl" value="LOG4J"/>
</settings>
<typeAliases>
<!-- MyBatis에서 사용되는 클래스들은 사용할 때 패키지명이 포함된
전체 이름을 사용해야되는데 이것을 대신해서 짧은 이름으로 사용하기 위한 별칭을 등록한다.
형식) <typeAlias type="패키지명을 포함한 전체이름" alias="별칭이름"/>
-->
<typeAlias type="kr.or.ddit.member.vo.MemberVO" alias="memVo"/>
<typeAlias type="kr.or.ddit.member.vo.ZipVO" alias="zipVo"/>
<typeAlias type="kr.or.ddit.board.vo.BoardVO" alias="bVo"/>
<typeAlias type="kr.or.ddit.board.vo.ReplyVO" alias="rVo"/>
</typeAliases>
<!-- DB에 연결 할 정보 설정하기 -->
<environments default="oracleDB">
<!-- 다른 DB도 연결할 수 있으므로 env는 여러개 올 수 있다 / id는 구분하기 위한 이름 -->
<environment id="oracleDB">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/><!-- value값에 프로퍼티스의 키값 작성 -->
<property name="url" value="${url}"/>
<property name="username" value="${user}"/>
<property name="password" value="${pass}"/>
</dataSource>
</environment>
</environments>
<!-- DB에서 사용되는 SQL문이 작성된 mapper파일을 등록하는 부분 -->
<mappers>
<!--
형식) <mapper resource="경로명/파일명.xml"/>
-->
<mapper resource="kr/or/ddit/mybatis/mappers/member-mapper.xml"/>
<mapper resource="kr/or/ddit/mybatis/mappers/board-mapper.xml"/>
</mappers>
</configuration>
board-mapper
<?xml version="1.0" encoding="UTF-8"?>
<!-- 이 문서는 myBatis에서 처리할 SQL문을 작성하는 문서입니다 -->
<!DOCTYPE mapper
PUBLIC "-//mybatis.org/DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- <mapper>태그의 namespace속성에 설정된 값은 Java소스에서 실행할 SQL문을 호출할 때 같이 사용되는 이름이다 -->
<mapper namespace="board">
<sql id="dynamicCondition">
<where>
<if test="!(stype == '' or sword == '')">
${stype} like '%'||#{sword}||'%'
</if>
</where>
</sql>
<!-- 게시판 리스트 가져오기 -->
<select id="allBoard" parameterType="map" resultType="bVo">
select A.* from
(select rownum as rnum , B.* from
( select * from boardtab
<include refid="dynamicCondition" />
order by num desc ) B
<!-- <= 태그가 아니고 글자로 인식 <![CDATA[ ]] -->
<![CDATA[
where rownum <= #{end}) A
where A.rnum >= #{start}
]]>
</select>
<select id="totalCount" parameterType="map" resultType="int">
select count(*) cnt from boardtab
<include refid="dynamicCondition" />
</select>
<insert id="insertBoard" parameterType="bVo">
insert into boardtab values(boardtab_num_seq.nextval, #{subject}, #{writer},
#{mail}, #{password}, #{content}, 0, #{wip}, sysdate)
</insert>
<update id="updateBoard" parameterType="bVo">
update boardtab set subject = #{subject}, mail=#{mail}, password=#{password}, content=#{content}, wip = #{wip}, wdate = sysdate
where num = #{num}
</update>
<delete id="deleteBoard" parameterType="int">
delete from boardtab where num = #{num}
</delete>
<update id="updateHit" parameterType="int">
update boardtab set hit=hit+1
where num = #{num}
</update>
<insert id="insertReply" parameterType="rVo">
insert into replytab values(replytab_renum_seq.nextval, #{bonum}, #{name}, #{cont}, sysdate)
</insert>
<update id="updateReply" parameterType="rVo">
update replytab set name=#{name}, cont=#{cont}, redate=sysdate
</update>
<delete id="deleteReply" parameterType="int">
delete from replytab where renum=#{renum}
</delete>
<select id="listReply" parameterType="int" resultType="rVo">
select * from replytab
where bonum=#{bonum}
order by renum desc
</select>
</mapper>
BoardVO
package kr.or.ddit.board.vo;
public class BoardVO {
private int num;
private String subject;
private String writer;
private String mail;
private String password;
private String content;
private int hit;
private String wip;
private String wdate;
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
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 int getHit() {
return hit;
}
public void setHit(int hit) {
this.hit = hit;
}
public String getWip() {
return wip;
}
public void setWip(String wip) {
this.wip = wip;
}
public String getWdate() {
return wdate;
}
public void setWdate(String wdate) {
this.wdate = wdate;
}
}
ReplyVO
package kr.or.ddit.board.vo;
public class ReplyVO {
private int renum;
private int bonum;
private String name;
private String cont;
private String redate;
public int getRenum() {
return renum;
}
public void setRenum(int renum) {
this.renum = renum;
}
public int getBonum() {
return bonum;
}
public void setBonum(int bonum) {
this.bonum = bonum;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCont() {
return cont;
}
public void setCont(String cont) {
this.cont = cont;
}
public String getRedate() {
return redate;
}
public void setRedate(String redate) {
this.redate = redate;
}
}
dao
package kr.or.ddit.board.dao;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.session.SqlSession;
import kr.or.ddit.board.vo.BoardVO;
import kr.or.ddit.board.vo.ReplyVO;
import kr.or.ddit.util.MyBatisUtil;
import sun.security.jca.GetInstance;
public class BoardDaoImpl implements IBoardDao {
private static BoardDaoImpl dao;
private BoardDaoImpl() {
}
public static BoardDaoImpl getInstance() {
if(dao==null) {
dao = new BoardDaoImpl();
}
return dao;
}
@Override
public List<BoardVO> getBoard(Map<String, Object> map) {
SqlSession session = null;
List<BoardVO> list = null;
try {
session = MyBatisUtil.getSqlSession();
list = session.selectList("board.allBoard", map);
} catch (Exception e) {
// TODO: handle exception
} finally {
session.close();
}
return list;
}
@Override
public int getTotalCount(Map<String, Object> map) {
SqlSession session = null;
int cnt = 0;
try {
session = MyBatisUtil.getSqlSession();
cnt = session.selectOne("board.totalCount", map);
} catch (Exception e) {
// TODO: handle exception
} finally {
session.close();
}
return cnt;
}
@Override
public int insertBoard(BoardVO bVo) {
SqlSession session = null;
int cnt = 0;
try {
session = MyBatisUtil.getSqlSession();
cnt = session.insert("board.insertBoard", bVo);
if(cnt>0) {
session.commit();
}
} catch (Exception e) {
// TODO: handle exception
} finally {
session.close();
}
return cnt;
}
@Override
public int updateBoard(BoardVO bVo) {
SqlSession session = null;
int cnt = 0;
try {
session = MyBatisUtil.getSqlSession();
cnt = session.update("board.updateBoard", bVo);
if(cnt>0) {
session.commit();
}
} catch (Exception e) {
// TODO: handle exception
} finally {
session.close();
}
return cnt;
}
@Override
public int deleteBoard(int num) {
SqlSession session = null;
int cnt = 0;
try {
session = MyBatisUtil.getSqlSession();
cnt = session.delete("board.deleteBoard", num);
} catch (Exception e) {
// TODO: handle exception
} finally {
session.commit();
session.close();
}
return cnt;
}
@Override
public int updateHit(int num) {
SqlSession session = null;
int cnt = 0;
try {
session = MyBatisUtil.getSqlSession();
cnt = session.update("board.updateHit", num);
if(cnt>0) {
session.commit();
}
} catch (Exception e) {
// TODO: handle exception
} finally {
session.close();
}
return cnt;
}
@Override
public int insertReply(ReplyVO rVo) {
SqlSession session = null;
int cnt = 0;
try {
session = MyBatisUtil.getSqlSession();
cnt = session.insert("board.insertReply", rVo);
if(cnt>0) {
session.commit();
}
} catch (Exception e) {
// TODO: handle exception
} finally {
session.close();
}
return cnt;
}
@Override
public int updateReply(ReplyVO rVo) {
SqlSession session = null;
int cnt = 0;
try {
session = MyBatisUtil.getSqlSession();
cnt = session.update("board.updateReply", rVo);
} catch (Exception e) {
// TODO: handle exception
} finally {
session.commit();
session.close();
}
return cnt;
}
@Override
public int deleteReply(int renum) {
SqlSession session = null;
int cnt = 0;
try {
session = MyBatisUtil.getSqlSession();
cnt = session.delete("board.deleteReply", renum);
} catch (Exception e) {
// TODO: handle exception
} finally {
session.commit();
session.close();
}
return cnt;
}
@Override
public List<ReplyVO> ListReply(int bonum) {
SqlSession session = null;
List<ReplyVO> list = null;
try {
session = MyBatisUtil.getSqlSession();
list = session.selectList("board.listReply", bonum);
} catch (Exception e) {
// TODO: handle exception
} finally {
session.close();
}
return list;
}
}
service
package kr.or.ddit.board.service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import kr.or.ddit.board.dao.BoardDaoImpl;
import kr.or.ddit.board.vo.BoardVO;
import kr.or.ddit.board.vo.PageVO;
import kr.or.ddit.board.vo.ReplyVO;
public class BoardServiceImpl implements IBoardService{
private static BoardServiceImpl service;
private BoardDaoImpl dao;
private BoardServiceImpl() {
dao = BoardDaoImpl.getInstance();
}
public static BoardServiceImpl getInstance() {
if(service==null) service = new BoardServiceImpl();
return service;
}
@Override
public List<BoardVO> getBoard(Map<String, Object> map) {
// TODO Auto-generated method stub
return dao.getBoard(map);
}
@Override
public int insertBoard(BoardVO bVo) {
// TODO Auto-generated method stub
return dao.insertBoard(bVo);
}
@Override
public int updateBoard(BoardVO bVo) {
// TODO Auto-generated method stub
return dao.updateBoard(bVo);
}
@Override
public int deleteBoard(int num) {
// TODO Auto-generated method stub
return dao.deleteBoard(num);
}
@Override
public int updateHit(int num) {
// TODO Auto-generated method stub
return dao.updateHit(num);
}
@Override
public int getTotalCount(Map<String, Object> map) {
// TODO Auto-generated method stub
return dao.getTotalCount(map);
}
@Override
public int insertReply(ReplyVO rVo) {
// TODO Auto-generated method stub
return dao.insertReply(rVo);
}
@Override
public int updateReply(ReplyVO rVo) {
// TODO Auto-generated method stub
return dao.updateReply(rVo);
}
@Override
public int deleteReply(int renum) {
// TODO Auto-generated method stub
return dao.deleteReply(renum);
}
@Override
public List<ReplyVO> ListReply(int bonum) {
// TODO Auto-generated method stub
return dao.ListReply(bonum);
}
@Override
public PageVO pageInfo(int page, String stype, String sword) {
PageVO pageVo = new PageVO();
// 전체 글 갯수 구하기
// count
Map<String, Object> map = new HashMap<String, Object>();
map.put("stype", stype);
map.put("sword", sword);
int count = this.getTotalCount(map);
pageVo.setCount(count);
int perList = pageVo.getPerList();
int perPage = pageVo.getPerPage();
// 전체 페이지 수 구하기
//totalPage
int totalPage = count/perList;
//totalPage = (int)Math.ceil((double)count/perList);
if(count%perList>0) totalPage++;
pageVo.setTotalPage(totalPage);
// page가 1일때 start 1 end 3
// page가 2일때 start 4 end 6
// page가 3일때 start 7 end 9
//start, end
int start = perList*(page-1)+1;
int end = perList*(page);
if(end > count) {
end = count;
}
pageVo.setStart(start);
pageVo.setEnd(end);
// page가 1일때 startpage 1 endpage 2
// page가 2일때 startpage 1 endpage 2
// page가 3일때 startpage 3 endpage 4
// page가 4일때 startpage 3 endpage 4
// page가 5일때 startpage 5 endpage 6
// page가 6일때 startpage 5 endpage 6
// page가 7일때 startpage 7 endpage 7
//startPage, endPage
int startPage = ((page-1) / perPage * perPage) +1;
int endPage = startPage+perPage -1;
if(endPage > totalPage) {
endPage = totalPage;
}
pageVo.setStartPage(startPage);
pageVo.setEndPage(endPage);
System.out.println("start ==>"+start);
System.out.println("end ==>"+end);
System.out.println("startpage ==>"+startPage);
System.out.println("endpage ==>"+endPage);
System.out.println("totalPage ==>"+totalPage);
return pageVo;
}
}
pageVO (서비스의 페이지 정보를 담을 VO)
package kr.or.ddit.board.vo;
public class PageVO {
// 출력되는 게시판의 번호 (rownum)
private int start;
private int end;
// 출력되는 페이지 갯수
private int startpage;
private int endpage;
private int totalpage;
private int count;
private static int perList = 3; // 글 리스트를 3개씩 출력
private static int perPage = 2; // 페이지 갯수의 묶음
public int getStart() {
return start;
}
public void setStart(int start) {
this.start = start;
}
public int getEnd() {
return end;
}
public void setEnd(int end) {
this.end = end;
}
public int getStartPage() {
return startpage;
}
public void setStartPage(int startPage) {
this.startpage = startPage;
}
public int getEndPage() {
return endpage;
}
public void setEndPage(int endPage) {
this.endpage = endPage;
}
public int getTotalPage() {
return totalpage;
}
public void setTotalPage(int totalPage) {
this.totalpage = totalPage;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public static int getPerList() {
return perList;
}
public static void setPerList(int perList) {
PageVO.perList = perList;
}
public static int getPerPage() {
return perPage;
}
public static void setPerPage(int perPage) {
PageVO.perPage = perPage;
}
}
BOARD관련 처리
☆☆ Board.jsp ☆☆
js의 메서드를 사용하여 출력한다
<%@page import="kr.or.ddit.member.vo.MemberVO"%>
<%@page import="com.google.gson.Gson"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- jsp에서는 백틱(`)의 ${}이 el태그로 인식한다 그걸을 인식하지않기위해 설정해야한다-->
<%@ page isELIgnored="true" %>
<!DOCTYPE html>
<html>
<head>
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css"
rel="stylesheet">
<script
src="https://cdn.jsdelivr.net/npm/jquery@3.6.3/dist/jquery.min.js"></script>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script>
<script
src="../js/board.js"></script>
<script
src="../js/jquery.serializejson.min.js"></script>
<meta charset="UTF-8">
<title>Insert title here</title>
<style>
ul {
width: 300px;
margin-left: auto;
margin-right: auto;
}
body * {
box-sizing: border-box;
}
nav, #write {
margin: 10px 5%;
}
nav a {
visibility: hidden;
}
#stype {
width: 100px;
}
#sword {
width: 150px;
}
p {
border: 1px dotted blue;
padding: 4px;
margin: 2px;
word-break: keep-all; /* 줄바꿈: 단어단위로 */
}
.p12 {
display: flex;
flex-direction: row;
}
.p1 {
flex: 70%;
}
.p2 {
flex: 30%;
text-align: right;
}
.card-body, .reply-body {
display: flex;
flex-direction: column;
}
.reply-body{
background : skyblue;
margin : 3px;
border : 1px dotted teal;
}
input[name=reply] {
height: 55px;
vertical-align: top;
}
textarea {
width: 70%;
vertical-align: top;
}
label {
display: inline-block;
width: 80px;
height: 30px;
}
#modifyform {
display: none;
}
#modifyform textarea {
vertical-align: bottom;
}
#btnok, #btnreset {
height: 40px;
}
</style>
<%
//로그인 세션 값 을 가져온다 - 최초로 실행시 값 이 없다
// 로그인했으면 이름 부분을 session에 저장된 이름을 넣어줌
// 수정과 삭제시에도 버튼을 활성화, 비활성화
MemberVO vo = (MemberVO) session.getAttribute("loginok");
//자바 객체를 json표현식으로 변환 - 직렬화
Gson gson = new Gson();
String ss = null;
// String name = null;
if (vo != null){
ss = gson.toJson(vo);
}
%>
<script>
uvo = <%=ss%>;
console.log(uvo);
console.log("uvo=" , uvo)
currentPage = 1;
propath = '<%=request.getContextPath()%>';
// 객체 선언 - 필요시 속성과 메서드를 동적으로 추가 사용 가능
const reply = {};
$(function() {
// 리스트 3개 출력하기- 최초 호출시 파라미터없다
// 외부 파일 board.js에 정의되어있는 script함수
listPerPage();
// 페이지 번호 클릭이벤트
$(document).on('click','.pageno',function(){
let page = parseInt($(this).text().trim());
currentPage = page;
listPerPage();
})
// 다음버튼 클릭 이벤트
$(document).on('click','#next',function(){
currentPage = parseInt($('.pageno').last().text() )+1;
listPerPage();
})
// 이전버튼 클릭 이벤트
$(document).on('click','#prev',function(){
currentPage = parseInt($('.pageno').first().text() )-1;
listPerPage();
})
// 검색 이벤트
$('#search').on('click',function(){
currentPage = 1;
listPerPage();
})
//글쓰기 이벤트
$('#write').on('click', function(){
$('.modal-title').text('글 작성');
if (uvo == null){
alert("로그인 하세요");
} else {
// 글쓰기 모달창 열기
$('#wModal').modal('show');
//세션에 저장된 이름을 폼에 출력
$('#wModal #wname').val(uvo.mem_name);
$('#wsubmit').show();
$('#usubmit').hide();
}
})
$('#wsubmit').on('click',function(){
// 입력한 모든 값 가져옴
fdata = $('#wform').serializeJSON();
insert();
// 지우고 닫음
$('#wform .indata').val("");
$('#wModal').modal('hide');
})
$('#usubmit').on('click',function(){
// 입력한 모든 값 가져옴
fdata = $('#wform').serializeJSON();
fdata.num = vbonum;
console.log(fdata);
boardUpdate();
// 지우고 닫음
$('#wform .indata').val("");
$('#wModal').modal('hide');
})
// 수정, 삭제, 댓글등록, 제목클릭, 댓글살제, 댓글 수정
$(document).on('click','.action',function(){
vnum = $(this).attr('idx'); // 게시판 글번호
vbonum = vnum;
vname = $(this).attr("name"); // 각 요소의 name특성
console.log(vbonum);
dthis = $(this);
if(vname == "title"){
// alert("게시판 글 "+vnum+"번의 댓글 리스트 가져오기")
aria = $(this).attr("aria-expanded");
// 전역변수 gthis를 선언하여 현재 이벤트가 발생되는 객체 this를 대입
gthis = $(this).parents('.card').find('.card-body');
if(aria == "true"){
// 조회수 증가
updateHit();
// this 댓글 리스트 출력하는 곳
replyList();
}
} else if(vname == "modify"){
let vparent = $(this).parents('.card');
$('.modal-title').text('글 수정');
// 글쓰기 모달창 열기
$('#wModal').modal('show');
$('#wModal #wsubject').val(vparent.find('.btn').text().trim());
$('#wModal #wname').val(vparent.find('.wr').text().trim());
$('#wModal #wmail').val(vparent.find('.em').text().trim());
$('#wModal #wcontent').val(vparent.find('.p3').text().trim());
$('#wsubmit').hide();
$('#usubmit').show();
} else if(vname == "delete"){
deleteBoard();
} else if(vname == "reply"){
// 게시판번호, 로그인한사람이름. 댓글내용
// 저장하기 위해서 reply라는 객체를 선언 후에 동적으로 속성을 추가
reply.bonum = vbonum;
if(uvo!=null){
reply.name = uvo.mem_name;
} else {
alert("로그인 하세요");
return false;
}
// 이전의 형제 찾기 prev()
// 다음번째에 있는 형제찾기 next()
reply.cont = $(this).prev().val();
replyWrite();
// 작성한 댓글 내용을 화면에서 지운다
$(this).prev().val("");
} else if(vname=="r_modify"){
vcontent = dthis.parents('.reply-body').find('.rp3').html().trim();
console.log("vcontent : "+vcontent);
dthis.parents('.reply-body').find('.rp3').text("");
dthis.parents('.reply-body').find('.rp2').hide();
reupcode = `<form>
<textarea rows='' cols='60' class='textCont'></textarea>
<input type='button' value='댓글수정' name='u_reply' class='action' idx='${vnum}'>
<input type='button' value='취소' name='cancel_reply' class='action' idx='${vnum}'></form>`;
dthis.parents('.reply-body').find('.rp3').append(reupcode);
rthis = dthis.parents('.reply-body');
rthis.find('.textCont').val(vcontent.replace(/<br>/g,"\n"));
} else if(vname=="r_delete"){
replyDelete();
} else if(vname=="u_reply"){
ucont = rthis.find('.textCont').val();
console.log("변경내용 : "+ucont);
replyUpdate();
} else if(vname=="cancel_reply"){
rthis.find('.rp3').text(vcontent);
rthis.find('.rp2').show();
}
})
})
</script>
</head>
<body>
<div id="modifyform">
<textarea rows="5" cols="50"></textarea>
<input type="button" value="확인" id="btnok"> <input
type="button" value="취소" id="btnreset">
</div>
<br>
<br>
<h1 style="margin-left : 10%">게시판</h1>
<nav class="navbar navbar-expand-sm navbar-dark bg-dark">
<div class="container-fluid">
<input type="button" value="글쓰기" id="write" data-bs-toggle="modal" data-bs-target="#myModal">
<!-- <a class="navbar-brand" href="javascript:void(0)">Logo</a> -->
<!-- 화면이 줄어들면 = 메뉴버튼이 나타나게하는 것 -->
<button class="navbar-toggler" type="button"
data-bs-toggle="collapse" data-bs-target="#mynavbar">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="mynavbar">
<ul class="navbar-nav me-auto">
<li class="nav-item"><a class="nav-link"
href="javascript:void(0)">Link</a></li>
<li class="nav-item"><a class="nav-link"
href="javascript:void(0)">Link</a></li>
</ul>
<form class="d-flex">
<select class="form-select" id="stype">
<option value="">전체</option>
<option value="writer">이름</option>
<option value="subject">제목</option>
<option value="content">내용</option>
</select> <input class="form-control me-2" type="text" id="sword"
placeholder="Search">
<button class="btn btn-primary" id="search" type="button">Search</button>
</form>
</div>
</div>
</nav>
<br>
<br>
<!-- 게시판 리스트 출력될 곳 -->
<div id="boardList"></div>
<br>
<!-- 페이지 리스트 출력될 곳 -->
<div id="pageList"></div>
<!-- 글쓰기 Modal -->
<div class="modal" id="wModal">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<h4 class="modal-title"></h4>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<!-- Modal body -->
<div class="modal-body">
<form id="wform" name="wform">
<label>이름</label><input class="indata" id="wname" name="writer"><br>
<label>제목</label><input class="indata" id="wsubject" name="subject"><br>
<label>이메일</label><input class="indata" id="wmail" name="mail"><br>
<label>비밀번호</label><input class="indata" id="wpw" name="password" type="password"><br>
<label>내용</label><textarea class="indata" rows="10" cols="100" name="content" id="wcontent"></textarea>
</form>
<br>
</div>
<!-- Modal footer -->
<div class="modal-footer">
<input type="button" value="수정" id="usubmit" class="btn btn-primary" data-bs-dismiss="modal">
<input type="button" value="전송" id="wsubmit" class="btn btn-success" data-bs-dismiss="modal">
<button type="button" class="btn btn-danger" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</body>
</html>
board읽기 ( 페이징)
▷ BoardList.do 서블릿 (forward)
StringBuffer로 데이터를 가져올 때 (역직렬화 시)
Map으로 데이터를 가져올 수 없기 때문에 별개의 VO값을 만들어 받아온다
forward로 전할시에
getRequestDispatcher('경로')
경로에서는 requset에서 요청하는 것이므로
request.contextPath()를 통해 폴더 경로를 나타낼 필요없이 바로 폴더명이나 파일이름을 작성한다
package kr.or.ddit.board.controller;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.gson.Gson;
import kr.or.ddit.board.service.BoardServiceImpl;
import kr.or.ddit.board.vo.BoardVO;
import kr.or.ddit.board.vo.PListVO;
import kr.or.ddit.board.vo.PageVO;
@WebServlet("/BoardList.do")
public class BoardList extends HttpServlet {
private static final long serialVersionUID = 1L;
private static BoardServiceImpl service = BoardServiceImpl.getInstance();
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
StringBuffer buf = new StringBuffer();
String line = null;
try {
BufferedReader read = request.getReader();
while ((line = read.readLine()) != null) {
buf.append(line);
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
// {page : 1, stype : "", sword : ""}
String reqdata = buf.toString();
Gson gson = new Gson();
PListVO vo = gson.fromJson(reqdata, PListVO.class);// 객체로 꺼내기위해선 VO가 필요
// vo.setpage(1) vo.setStype("") vo.setSword("")를 실행한 것과 같다
Map<String, Object> map = new HashMap<String, Object>();
map.put("sword", vo.getSword());
map.put("stype", vo.getStype());
PageVO pVo = service.pageInfo(vo.getPage(), vo.getStype(), vo.getSword());
map.put("start", pVo.getStart());
map.put("end", pVo.getEnd());
// 실제 리스트 3개씩 꺼내는 메서드 호출
List<BoardVO> list = service.getBoard(map);
/*
String json = gson.toJson(list);
response.setCharacterEncoding("utf-8");
response.setContentType("utf-8");
PrintWriter out = response.getWriter();
out.write(json);
response.flushBuffer();
*/
request.setAttribute("list", list);
request.setAttribute("startp", pVo.getStartPage());
request.setAttribute("endp", pVo.getEndPage());
request.setAttribute("totalp", pVo.getTotalPage());
request.getRequestDispatcher("/boardview/list.jsp").forward(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
웹서버의 json정보를 가져올 VO (PListVO)
더보기
package kr.or.ddit.board.vo;
public class PListVO {
private int page;
private String stype;
private String sword;
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public String getStype() {
return stype;
}
public void setStype(String stype) {
this.stype = stype;
}
public String getSword() {
return sword;
}
public void setSword(String sword) {
this.sword = sword;
}
}
리스트 뽑아낼 jsp - list.jsp
<%@page import="com.google.gson.JsonElement"%>
<%@page import="com.google.gson.Gson"%>
<%@page import="com.google.gson.JsonObject"%>
<%@page import="kr.or.ddit.board.vo.BoardVO"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
// controller에서 저장한 데이터 꺼내기
List<BoardVO> list = (List<BoardVO>) request.getAttribute("list");
int sp = (Integer) request.getAttribute("startp");
int ep = (Integer) request.getAttribute("endp");
int tp = (Integer) request.getAttribute("totalp");
JsonObject obj = new JsonObject();
obj.addProperty("sp", sp);
obj.addProperty("ep", ep);
obj.addProperty("tp", tp);
Gson gson = new Gson();
JsonElement result = gson.toJsonTree(list);
obj.add("datas", result);
out.print(obj);
out.flush();
/*
Gson gson = new Gson();
String result = gson.toJson(list)
*/
%>
게시판 작성
boardWrite 서블릿
package kr.or.ddit.board.controller;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.gson.Gson;
import kr.or.ddit.board.service.BoardServiceImpl;
import kr.or.ddit.board.vo.BoardVO;
@WebServlet("/BoardInsert.do")
public class BoardInsert extends HttpServlet {
private static final long serialVersionUID = 1L;
private static BoardServiceImpl service = BoardServiceImpl.getInstance();
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
StringBuffer buf = new StringBuffer();
String line = null;
try {
BufferedReader read = request.getReader();
while ((line = read.readLine()) != null) {
buf.append(line);
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
String reqdata = buf.toString();
Gson gson = new Gson();
BoardVO bvo = gson.fromJson(reqdata, BoardVO.class);
String wip = request.getRemoteAddr();
System.out.println(wip);
bvo.setWip(wip);
int cnt=service.insertBoard(bvo);
/*
* PrintWriter out = response.getWriter();
* out.write(cnt);
* response.flushBuffer();
*/
request.setAttribute("cnt", cnt);
request.getRequestDispatcher("/boardview/result.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
게시판 작성/수정/삭제 + 댓글 작성/수정/삭제 출력하는 jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
// insert, update, delete실행 시 공통으로 사용하는 view페이지
// 각 controller에서 결과값을 request에 저장시 cnt라는 이름으로 저장되어야함
int cnt = (int)request.getAttribute("cnt");
if(cnt > 0){
%>
{
"flag" : "success"
}
<%
} else {
%>
{
"flag" : "fail"
}
<%
}
%>
게시판 수정
BoardUpdate Servlet
package kr.or.ddit.board.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.gson.Gson;
import kr.or.ddit.board.service.BoardServiceImpl;
import kr.or.ddit.board.vo.BoardVO;
import kr.or.ddit.util.StreamData;
@WebServlet("/boardUpdate.do")
public class BoardUpdate extends HttpServlet {
private static final long serialVersionUID = 1L;
private static BoardServiceImpl service = BoardServiceImpl.getInstance();
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String reqdata = StreamData.dataChange(request);
Gson gson = new Gson();
BoardVO bvo = gson.fromJson(reqdata, BoardVO.class);
String wip = request.getRemoteAddr();
bvo.setWip(wip);
int cnt=service.updateBoard(bvo);
request.setAttribute("cnt", cnt);
request.getRequestDispatcher("/boardview/result.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
게시판 삭제
BoardDelete Servlet
package kr.or.ddit.board.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import kr.or.ddit.board.service.BoardServiceImpl;
import kr.or.ddit.board.service.IBoardService;
/**
* Servlet implementation class BoardDelete
*/
@WebServlet("/boardDelete.do")
public class BoardDelete extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int num = Integer.parseInt(request.getParameter("num"));
IBoardService service = BoardServiceImpl.getInstance();
int cnt = service.deleteBoard(num);
request.setAttribute("cnt", cnt);
request.getRequestDispatcher("/boardview/result.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
조회수 증가 처리
updateHit Servlet
package kr.or.ddit.board.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import kr.or.ddit.board.service.BoardServiceImpl;
import kr.or.ddit.board.service.IBoardService;
@WebServlet("/updateHit.do")
public class UpdateHit extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int num = Integer.parseInt(request.getParameter("num"));
IBoardService service = BoardServiceImpl.getInstance();
int cnt = service.updateHit(num);
request.setAttribute("cnt", cnt);
request.getRequestDispatcher("/boardview/result.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
댓글 작성
replyWrite Servlet
package kr.or.ddit.board.controller;
import java.io.BufferedReader;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.gson.Gson;
import kr.or.ddit.board.service.BoardServiceImpl;
import kr.or.ddit.board.service.IBoardService;
import kr.or.ddit.board.vo.ReplyVO;
@WebServlet("/ReplyWrite.do")
public class ReplyWrite extends HttpServlet {
private static final long serialVersionUID = 1L;
private IBoardService service = BoardServiceImpl.getInstance();
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
StringBuffer buf = new StringBuffer();
String line = null;
try {
BufferedReader reader = request.getReader();
if( (line=reader.readLine())!=null) {
buf.append(line);
}
} catch (Exception e) {
// TODO: handle exception
}
String reqdata = buf.toString();
Gson gson = new Gson();
ReplyVO rvo = gson.fromJson(reqdata, ReplyVO.class);
int cnt = service.insertReply(rvo);
request.setAttribute("cnt", cnt);
request.getRequestDispatcher("/boardview/result.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
댓글 전체 출력
replyList Servlet
package kr.or.ddit.board.controller;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import kr.or.ddit.board.service.BoardServiceImpl;
import kr.or.ddit.board.service.IBoardService;
import kr.or.ddit.board.vo.ReplyVO;
@WebServlet("/replyList.do")
public class ReplyList extends HttpServlet {
private static final long serialVersionUID = 1L;
private IBoardService service = BoardServiceImpl.getInstance();
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int bonum = Integer.parseInt(request.getParameter("bonum"));
List<ReplyVO> list = service.ListReply(bonum);
request.setAttribute("list", list);
request.getRequestDispatcher("/boardview/replyList.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
댓글 리스트 출력 jsp
<%@page import="com.google.gson.Gson"%>
<%@page import="kr.or.ddit.board.vo.ReplyVO"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
// controller에서 저장한 데이터 꺼내기
List<ReplyVO> list = (List<ReplyVO>) request.getAttribute("list");
Gson gson = new Gson();
String result = gson.toJson(list);
out.print(result);
out.flush();
%>
댓글 수정
ReplyUpdate Servlet
package kr.or.ddit.board.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import kr.or.ddit.board.service.BoardServiceImpl;
import kr.or.ddit.board.service.IBoardService;
import kr.or.ddit.board.vo.ReplyVO;
@WebServlet("/replyUpdate.do")
public class ReplyUpdate extends HttpServlet {
private static final long serialVersionUID = 1L;
private IBoardService service = BoardServiceImpl.getInstance();
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int renum = Integer.parseInt(request.getParameter("renum"));
String cont = request.getParameter("cont");
ReplyVO rVo = new ReplyVO();
rVo.setRenum(renum);
rVo.setCont(cont);
int cnt = service.updateReply(rVo);
request.setAttribute("cnt", cnt);
request.getRequestDispatcher("/boardview/result.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
댓글 삭제
ReplyDelete Servlet
package kr.or.ddit.board.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import kr.or.ddit.board.service.BoardServiceImpl;
import kr.or.ddit.board.service.IBoardService;
@WebServlet("/replyDelete.do")
public class ReplyDelete extends HttpServlet {
private static final long serialVersionUID = 1L;
private IBoardService service = BoardServiceImpl.getInstance();
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
int renum = Integer.parseInt(request.getParameter("renum"));
int cnt = service.deleteReply(renum);
request.setAttribute("cnt", cnt);
request.getRequestDispatcher("/boardview/result.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
'웹프로그래밍 > jQuery' 카테고리의 다른 글
[jQuery] 회원가입페이지 만들기★ , serialize (0) | 2024.05.31 |
---|---|
[jQuery] 비동기 fetch, 직렬화 (0) | 2024.05.29 |
[jQuery] Servlet을 활용한 promise (0) | 2024.05.28 |
[jQuery] 비동기 AJAX (json) (0) | 2024.05.27 |
[jQurey] 비동기 AJAX (0) | 2024.05.24 |