[Spring 18-2] 페이징 처리 관련 예제 - 글쓰기 게시판

임승현·2023년 3월 6일

Spring

목록 보기
44/46

🌈Step_1 테이블 만들기

create table restboard(num number primary key, writer varchar2(50), content varchar2(100), regdate date);
create sequence restboard_seq;

🌈Step_2 DTO 클래스 생성

📃RestBoard.java

※ xyz.itwill10.dto 패키지에 RestBoard.java 클래스 생성

package xyz.itwill10.dto;
//
import lombok.Data;
//
@Data
public class RestBoard {
	private int num;
	private String writer;
	private String content;
	private String regdate;
}

🌈Step_3 매퍼 파일 생성

📃RestBoardMapper.xml

※ xyz.itwill10.mapper 패키지에 RestBoardMapper.xml 파일 생성

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="xyz.itwill10.mapper.RestBoardMapper">
	<!-- =============================================================================================== -->
	<insert id="insertRestBoard">
		<selectKey resultType="int" keyProperty="num" order="BEFORE">
			select restboard_seq.nextval from dual
		</selectKey>
		insert into restboard values(#{num},#{writer},#{content},sysdate)
	</insert>
	<!-- =============================================================================================== -->
	<update id="updateRestBoard">
		update restboard set writer=#{writer},content=#{content} where num=#{num}
	</update>
	<!-- =============================================================================================== -->
	<delete id="deleteRestBoard">
		delete from restboard where num=#{num}
	</delete>
	<!-- =============================================================================================== -->
	<!-- 이게 있어야지 페이징 처리 가능 -->
	<select id="selectRestBoardCount" resultType="int">
		select count(*) from restboard
	</select>
	<!-- =============================================================================================== -->
	<select id="selectRestBoard" resultType="RestBoard">
		select * from restboard where num=#{num}
	</select>
	<!-- =============================================================================================== -->
	<select id="selectRestBoardList" resultType="RestBoard">
		select * from (select rownum rn, board.* from (select * from restboard order by num desc) board) where rn between #{startRow} and #{endRow}
	</select>
</mapper>

📃RestBoardMapper.java(인터페이스)

※ xyz.itwill10.mapper 패키지에 RestBoardMapper.java 인터페이스 파일 생성

package xyz.itwill10.mapper;
//
import java.util.List;
import java.util.Map;
import xyz.itwill10.dto.RestBoard;
//
public interface RestBoardMapper {
	int insertRestBoard(RestBoard restBoard);
	int updateRestBoard(RestBoard restBoard);
	int deleteRestBoard(int num);
	int selectRestBoardCount();
	RestBoard selectRestBoard(int num);
	List<RestBoard> selectRestBoardList(Map<String, Object> map);//startRow와 endRow에 대한 DTO가 없어서 Map을 사용
}

🌈Step_4 DAO 클래스 생성

📃RestBoardDAO.java(인터페이스)

※ xyz.itwill10.dao 패키지에 RestBoardDAO.java 인터페이스 생성

package xyz.itwill10.dao;
//
import java.util.List;
import java.util.Map;
import xyz.itwill10.dto.RestBoard;
//
public interface RestBoardDAO {
	int insertRestBoard(RestBoard restBoard);
	int updateRestBoard(RestBoard restBoard);
	int deleteRestBoard(int num);
	int selectRestBoardCount();
	RestBoard selectRestBoard(int num);
	List<RestBoard> selectRestBoardList(Map<String, Object> map);
}

📃RestBoardDAOImpl.java

※ xyz.itwill10.dao 패키지에 RestBoardDAOImpl.java 클래스 생성

package xyz.itwill10.dao;
//
import java.util.List;
import java.util.Map;
import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;
import lombok.RequiredArgsConstructor;
import xyz.itwill10.dto.RestBoard;
import xyz.itwill10.mapper.RestBoardMapper;
//
@Repository
@RequiredArgsConstructor
public class RestBoardDAOImpl implements RestBoardDAO {
	private final SqlSession sqlSession;
	//
	@Override
	public int insertRestBoard(RestBoard restBoard) {
		return sqlSession.getMapper(RestBoardMapper.class).insertRestBoard(restBoard);
	}
	@Override
	public int updateRestBoard(RestBoard restBoard) {
		return sqlSession.getMapper(RestBoardMapper.class).updateRestBoard(restBoard);
	}
	@Override
	public int deleteRestBoard(int num) {
		return sqlSession.getMapper(RestBoardMapper.class).deleteRestBoard(num);
	}
	@Override
	public int selectRestBoardCount() {
		return sqlSession.getMapper(RestBoardMapper.class).selectRestBoardCount();
	}
	@Override
	public RestBoard selectRestBoard(int num) {
		return sqlSession.getMapper(RestBoardMapper.class).selectRestBoard(num);
	}
	@Override
	public List<RestBoard> selectRestBoardList(Map<String, Object> map) {
		return sqlSession.getMapper(RestBoardMapper.class).selectRestBoardList(map);
	}
}

🌈Step_5 Service 클래스 생성

📃RestBoardService.java(인터페이스)

※ xyz.itwill10.service 패키지에 RestBoardService.java 인터페이스 파일 생성

package xyz.itwill10.service;
//
import java.util.List;
import java.util.Map;
import xyz.itwill10.dto.RestBoard;
//
public interface RestBoardService {
	void addRestBoard(RestBoard restBoard);
	void modifyRestBoard(RestBoard restBoard);
	void removeRestBoard(int num);
	int getRestBoardCount();
	RestBoard getRestBoard(int num);
	List<RestBoard> getRestBoardList(Map<String, Object> map);
}

📃RestBoardServiceImpl.java

※ xyz.itwill10.service 패키지에 RestBoardServiceImpl.java 클래스 생성

package xyz.itwill10.service;
//
import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import lombok.RequiredArgsConstructor;
import xyz.itwill10.dao.RestBoardDAO;
import xyz.itwill10.dto.RestBoard;
//
@Service
@RequiredArgsConstructor
public class RestBoardServiceImpl implements RestBoardService {
	private final RestBoardDAO restBoardDAO;
	//
	@Transactional
	@Override
	public void addRestBoard(RestBoard restBoard) {
		restBoardDAO.insertRestBoard(restBoard);
	}
	//
	@Transactional
	@Override
	public void modifyRestBoard(RestBoard restBoard) {
		/*
		if(restBoardDAO.selectRestBoard(restBoard.getNum())==null) {
			throw new Exception("해당 게시글을 찾을 수 없습니다.");
		}
		*/
		restBoardDAO.updateRestBoard(restBoard);
	}
	//
	@Transactional
	@Override
	public void removeRestBoard(int num) {
		restBoardDAO.deleteRestBoard(num);
	}
	//
	@Override
	public int getRestBoardCount() {
		return restBoardDAO.selectRestBoardCount();
	}
	//
	@Override
	public RestBoard getRestBoard(int num) {
		return restBoardDAO.selectRestBoard(num);
	}
	//
	@Override
	public List<RestBoard> getRestBoardList(Map<String, Object> map) {
		return restBoardDAO.selectRestBoardList(map);
	}
}

🌈Step_6 Controller 클래스 생성

📃RestBoardController.java

※ xyz.itwill10.controller 패키지에 RestBoardController.java 클래스 생성

package xyz.itwill10.controller;
//
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.util.HtmlUtils;
import lombok.RequiredArgsConstructor;
import xyz.itwill10.dto.RestBoard;
import xyz.itwill10.service.RestBoardService;
import xyz.itwill10.util.Pager;
//
//REST 기능을 제공하는 페이지를 요청하여 요청 처리 메소드가 정삭적으로 실행되는지 확인하기위해 Advanced REST Client 크롬앱을 설치하여 사용
//→ REST API 테스트 프로그램
//
//REST 기능을 제공하는 요청 처리 메소드의 페이지 요청 방식
//→ @RequestMapping 어노테이션의 method 속성값을 사용하여 구분 - @GetMapping, @PostMapping 등의 어노테이션 사용 가능
//→ 페이지 요청방식 : GET(검색), POST(삽입), PUT(전체 변경), PATCH(부분 변경), DELETE(삭제) 등
//→ PUT, PATCH, DELETE, 등의 요청방식은 POST 요청방식에서 파생된 요청방식 - 리퀘스트 메세지의 몸체부에 전달값 저장
//
@Controller
//@RestController : REST 기능을 제공하는 요청 처리 메소드만 작성된 Controller 클래스를 Spring Bean으로 등록하기 위한 어노테이션
//→ REST 기능을 제공하는 요청 처리 메소드에 @ResponsBody 어노테이션을 사용하지 않아도 반환값을 텍스트 데이터로 응답 처리 가능 
@RequiredArgsConstructor
public class RestBoardController {
	private final RestBoardService restBoardService;
	//
	@RequestMapping("/board")
	public String restBoard() {
		return "rest/board";
	}
	//
	//페이지 번호를 전달받아 RESTBOARD 테이블에 저장된 게시글 목록 중 해당 페이지 번호의 범위에 게시글 목록 검색하여 JSON 형식의 데이타로 응답하는 요청 처리 메소드
	//→ 게시글 목록을 페이징 처리하여 출력하기 위해 요청 페이지 번호의 게시글 목록과 페이지 번호 출력 관련 값이
	//	 저장된 객체를 Map 객체의 엔트리로 저장하여 JSON 형식의 데이터로 응답 처리되도록 반환
	@RequestMapping(value = "/board_list", method = RequestMethod.GET)
	@ResponseBody
	public Map<String, Object> restBoard(@RequestParam(defaultValue = "1") int pageNum) {
		//System.out.println("pageNum = "+pageNum);
		//
		//RESTBOARD 테이블에 저장된 모든 게시글의 갯수를 반환하는 메소드 호출
		int totalBoard=restBoardService.getRestBoardCount();
		int pageSize=5;//하나의 페이지에 출력될 게시글의 갯수를 저장
		int blockSize=5;//하나의 블럭에 출력될 페이지 번호의 갯수 저장
		//
		//페이지 처리 관련 값을 필드에 저장된 Pager 객체 생성
		Pager pager=new Pager(pageNum, totalBoard, pageSize, blockSize);
		//
		//RestBoardService 클래스의 getRestBoardList() 메소드를 호출하기 위해 Map 객체 생성
		//→ Map 객체에는 요청 페이지의 시작 행번호와 종료 행번호를 엔트리로 저장하여 SQL 명령에서 사용
		Map<String, Object> pageMap=new HashMap<String, Object>();
		pageMap.put("startRow", pager.getStartRow());
		pageMap.put("endRow", pager.getEndRow());
		//요청 페이지 번호에 대한 게시글 목록을 List 객체로 반환받아 저장
		List<RestBoard> restBoardList=restBoardService.getRestBoardList(pageMap);
		//
		//처리결과를 저장하기 위한 Map 객체 생성 - Map 객체를 반환하여 JSON 형식의 데이터로 응답
		//→ Map 객체에는 게시글 목록(List 객체)과 페이징 처리 관련 값이 저장된 객체(Pager 객체)를 엔트리로 저장
		Map<String, Object> resultMap=new HashMap<String, Object>();
		resultMap.put("restBoardList", restBoardList);
		resultMap.put("pager", pager);
		//
		return resultMap;//Map 객체를 반환하여 JSON 형식의 데이터로 응답
	}
	//
	//게시글을 전달받아 RESTBOARD 테이블에 삽입하고 처리결과를 일반 텍스트로 응답하는 요청 처리 메소드
	//→ [application/json] 형식으로 전달된 값을 Java 객체로 제공받기 위해 매개변수에 @RequestBody 어노테이션 사용
	@RequestMapping(value = "/board_add", method = RequestMethod.POST)
	@ResponseBody
	public String restBoardAdd(@RequestBody RestBoard restBoard) {
		//HtmlUtils.htmlEscape(String str) : 전달받은 문자열에서 HTML 태그 관련 문자를 회피문자(Escape Character)로 변환하여 반환하는 메소드 - XSS 공격에 대한 방어
		restBoard.setContent(HtmlUtils.htmlEscape(restBoard.getContent()));
		restBoardService.addRestBoard(restBoard);
		return "success";
	}
	//
	//글번호를 전달받아 RESTBOARD 테이블에 저장된 해당 글번호의 게시글을 검색하여 JSON 형식의 텍스트 데이타로 응답하는 요청 처리 메소드
	@RequestMapping(value="/board_view", method = RequestMethod.GET)
	@ResponseBody
	public RestBoard restBoardView(@RequestParam int num) {
		return restBoardService.getRestBoard(num);
	}
	//
	//게시글을 전달받아 RESTBOARD 테이블에 저장된 해당 게시글을 변경하고 처리결과를 일반 텍스트로 응답하기 위한 요청 처리 메소드
	//→ 페이지 요청 방식을 여러개로 설정할 경우 @RequestMapping 어노테이션의 method 속성값으로 배열 사용 가능
	@RequestMapping(value="/board_modify", method = {RequestMethod.PUT, RequestMethod.PATCH})
	@ResponseBody
	public String restBoardModify(@RequestBody RestBoard restBoard) {
		restBoardService.modifyRestBoard(restBoard);
		return "success";
	}
	//요청 URL 주소의 글번호를 전달받아 RESTBOARD 테이블에 저장된 해당 글번호의 게시글을 삭제하고 처리결과를 일반 텍스트로 응답하기 위한 요청 처리 메소드
	//→ 요청 URL 주소를 사용하여 전달된 값은 @RequestMapping 어노테이션의 value 속성값에서 
	//	{이름} 형식으로 표현 가능 - @PathVariable 어노테이션을 사용하여 전달값을 매개변수에 저장
	//@PathVariable : URL 주소로 제공된 값을 요청 처리 메소드의 매개변수에 저장하기 위한 어노테이션
	//→ 요청 URL 주소에서 표현된 이름과 매개변수의 이름이 반드시 같아야만 매개변수에 값 저장 가능
	//→ @PathVariable 어노테이션에 value 속성값을 사용하여 요청 URL 주소에서 표현된 이름으로 제공된 값을 얻어와 매개변수에 저장 가능
	@RequestMapping(value="/board_remove/{num}", method = RequestMethod.DELETE)
	@ResponseBody
	public String restBoardRemove(@PathVariable int num) {
		restBoardService.removeRestBoard(num);
		return "success";
	}
}

🌈Step_7 Pager 클래스 생성

📢페이징 처리 관련 값을 필드에 저장하기 위한 클래스

📃pager.java

※ xyz.itwill10.util 패키지에 pager.java 클래스 생성

package xyz.itwill10.util;
//
import lombok.Data;
//페이징 처리 관련 값을 필드에 저장하기 위한 클래스
@Data
public class Pager {
	//생성자를 이용하여 초기값을 전달받아 필드에 저장
	private int pageNum;//요청 페이지의 번호 저장
	private int totalBoard;//전체 게시글의 갯수 저장
	private int pageSize;//하나의 페이지에 출력될 게시글의 갯수 저장
	private int blockSize;//하나의 블럭에 출력될 페이지 번호의 갯수 저장
	//
	//생성자로 초기화된 필드값을 계산하여 결과값을 필드에 저장
	private int totalPage;//전체 페이지의 갯수 저장
	private int startRow;//요청 페이지에 출력될 게시글의 시작 행번호
	private int endRow;//요청 페이지에 출력될 게시글의 종료 행번호
	private int startPage;//현재 블럭에 출력될 시작 페이지 번호
	private int endPage;//현재 블럭에 출력될 종료 페이지 번호
	private int prevPage;//이전 블럭에 출력될 시작 페이지 번호
	private int nextPage;//다음 블럭에 출력될 시작 페이지 번호
	//
	//생성자로 생성함
	public Pager(int pageNum, int totalBoard, int pageSize, int blockSize) {
		super();
		this.pageNum = pageNum;
		this.totalBoard = totalBoard;
		this.pageSize = pageSize;
		this.blockSize = blockSize;
		//
		calcPage();
	}
	//계산 결과값을 필드에 저장하는 메소드 - 생성자에서 호출하여 사용
	private void calcPage() {
		totalPage=(int)Math.ceil((double)totalBoard/pageSize);
		if(pageNum<=0 || pageNum>totalPage) {
			pageNum=1;
		}
		//
		startRow=(pageNum-1)*pageSize+1;
 		endRow=pageNum*pageSize;
		if(endRow>totalBoard) {
			endRow=totalBoard;
		}
		//
		startPage=(pageNum-1)/blockSize*blockSize+1;
		endPage=startPage+blockSize-1;
		if(endPage>totalPage) {
			endPage=totalPage;
		}
		//
		prevPage=startPage-blockSize;
		nextPage=startPage+blockSize;
	}
}

🌈Step_8 JSP 작성

📃board.jsp

※ WEB-INF/views/rest 폴더에 board.jsp 작성

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SPRING</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<style type="text/css">
#btnDiv {
	margin: 10px;
}
#restBoardTable {
	border: 1px solid black;
	border-collapse: collapse; 
}
#restBoardTable td, #restBoardTable th {
	border: 1px solid black;
	padding: 3px;
}
.inputDiv {
	width: 240px;
	height: 80px;
	border: 2px solid black;
	background-color: gray;
	position: absolute;
	top: 50%;
	left: 50%;
	margin-top: -40px;
	margin-left: -120px;
	padding: 5px;
	z-index: 100;
	display: none;
}
</style>
</head>
<body>
	<h1>RestBoard</h1>
	<hr>
	<div id="btnDiv">
		<button type="button" id="writeBtn">글쓰기</button>
	</div>
	<%-- 게시글 목록을 출력하는 태그 --%>
	<div id="restBoardListDiv"></div>
	<%-- 페이지 번호를 출력하는 태그 --%>
	<div id="pageNumDiv"></div>
	<%-- 신규 게시글을 입력받기 위한 태그 --%>
	<div id="insertDiv" class="inputDiv">
		<table>
			<tr>
				<td>작성자</td>
				<td><input type="text" id="insertWriter" class="insert"></td>
			</tr>
			<tr>
				<td>내용</td>
				<td><input type="text" id="insertContent" class="insert"></td>
			</tr>
			<tr>
				<td colspan="2">
					<button type="button" id="insertBtn">저장</button>
					<button type="button" id="cancelInsertBtn">취소</button>
				</td>
			</tr>
		</table>
	</div>
	<%-- 변경 게시글을 입력받기 위한 태그 --%>
	<div id="updateDiv" class="inputDiv">
		<input type="hidden" id="updateNum">
		<table>
			<tr>
				<td>작성자</td>
				<td><input type="text" id="updateWriter" class="update"></td>
			</tr>
			<tr>
				<td>내용</td>
				<td><input type="text" id="updateContent" class="update"></td>
			</tr>
			<tr>
				<td colspan="2">
					<button type="button" id="updateBtn">변경</button>
					<button type="button" id="cancelUpdateBtn">취소</button>
				</td>
			</tr>
		</table>
	</div>
	<script type="text/javascript">
	//현재 요청 페이지의 번호를 저장하기 위한 전역변수 
	//→ 모든 함수에서 사용 가능하며 프로그램 종료 전까지 값을 유지
	var page=1;
	//
	//특정 페이지 번호의 게시글 목록을 출력하는 함수 호출
	boardListDisplay(page);
	//
	//RESTBOARD 테이블에 저장된 게시글 목록을 페이징 처리하여 검색하고 처리결과를 JSON 형식의 데이터로 응답하는 페이지(board_list)를 AJAX 기능으로 요청 
	//→ 응답받은 JSON 형식의 데이터로 게시글 목록 출력 태그를 변경
	function boardListDisplay(pageNum) {
		page=pageNum;
		$.ajax({
			type: "get",
			url: "${pageContext.request.contextPath}/board_list?pageNum="+pageNum,
			dataType: "json",
			success: function(result) {
				//alert(result);//[object Object] >> 자바스크립트 Object 객체
				//
				//매개변수로 제공받은 자바스크립트 객체를 HTML로 변경하여 게시글 목록 출력 태그 변경
				if(result.restBoardList.length==0) {//검색된 게시글이 없는 경우
					var html="<table id='restBoardTable'>";
					html+="<tr>";
					html+="<th width='800' colspan='6'>검색된 게시글이 없습니다.</th>";
					html+="</tr>";
					html+="</table>";
					$("#restBoardListDiv").html(html);
					return;
				}
				//
				var html="<table id='restBoardTable'>";
				html+="<tr>";
				html+="<th width='50'>번호</th>";
				html+="<th width='100'>작성자</th>";
				html+="<th width='350'>내용</th>";
				html+="<th width='200'>작성일</th>";
				html+="<th width='50'>변경</th>";
				html+="<th width='50'>삭제</th>";
				html+="</tr>";
				$(result.restBoardList).each(function() {//게시글 목록을 반복 처리
					html+="<tr>";
					html+="<td align='center'>"+this.num+"</td>";
					html+="<td align='center'>"+this.writer+"</td>";
					html+="<td>"+this.content+"</td>";
					html+="<td align='center'>"+this.regdate+"</td>";
					html+="<td align='center'><button type='button' onclick='modify("+this.num+");'>변경</button></td>";
					html+="<td align='center'><button type='button' onclick='remove("+this.num+");'>삭제</button></td>";
					html+="</tr>";
				});
				html+="</table>";
				//
				$("#restBoardListDiv").html(html);
				//
				//페이지 번호를 출력하는 함수 호출
				pageNumDisplay(result.pager)
			},
			error: function(xhr) {
				alert("에러코드(게시글 목록 검색) = "+xhr.status)
			}
		});
	}
	//
	//페이지 번호를 출력하는 태그를 변경하는 함수 - 페이지 번호 출력
	function pageNumDisplay(pager) {
		var html="";
		//
		if(pager.startPage > pager.blockSize) {
			html+="<a href='javascript:boardListDisplay("+pager.prevPage+")'>[이전]</a>";
		}
		//
		for(i=pager.startPage;i<=pager.endPage;i++) {
			if(pager.pageNum!=i) {
				html+="<a href='javascript:boardListDisplay("+i+")'>["+i+"]</a>";
			} else {
				html+="["+i+"]";
			}
		}
		//
		if(pager.endPage != pager.totalPage) {
			html+="<a href='javascript:boardListDisplay("+pager.nextPage+")'>[다음]</a>";
		}
		//
		$("#pageNumDiv").html(html);
	}
	//
	//[글쓰기] 태그를 클릭한 경우 호출되는 이벤트 처리 함수
	$("#writeBtn").click(function() {
		//변경 게시글을 입력받기 위한 태그 초기화
		$(".update").val("");//입력태그 초기화
		$("#updateDiv").hide();//태그 숨김
		//
		//신규 게시글을 입력받기 위한 태그 출력
		$("#insertDiv").show();
	});
	//
	//신규 게시글을 입력받기 위한 태그에서 [저장] 태그를 클릭한 경우 호출되는 이벤트 처리 함수
	//→ 사용자 입력값을 얻어와 RESTBOARD 테이블에 삽입하는 페이지를 AJAX 기능으로 요청하여 처리결과를 제공받아 응답 처리
	$("#insertBtn").click(function() {
		var writer=$("#insertWriter").val();
		var content=$("#insertContent").val();
		//
		if(writer=="") {
			alert("작성자를 입력해 주세요.");
			return;
		}
		//
		if(content=="") {
			alert("내용 입력해 주세요.");
			return;
		}
		//
		$.ajax({
			type: "post",
			url: "${pageContext.request.contextPath}/board_add",
			//headers : 요청정보가 저장된 리퀘스트 메세지의 머릿부(Header)를 변경하기 위한 속성
			//→ 리퀘스트 메세지의 머릿부에서 몸체부에 저장된 전달값에 대한 문서형식(MimeType)을 변경
			//headers: {"contentType":"application/json"},
			//contentType : 리퀘스트 몸체부에 저장된 전달값에 대한 문서형식을 변경하기 위한 속성
			//→ 리퀘스트 몸체부에 저장된 전달값을 JSON 형식의 텍스트 데이터로 전달
			//→ 요청 처리 메소드의 매개변수에서 @RequestBody 어노테이션을 사용하여 모든 전달값을 Java 객체로 제공받아 사용 - 전달값은 Java 객체의 필드값으로 저장
			contentType: "application/json",
			//JSON.stringify(object) : JavaScript 객체를 전달받아 JSON 형식의 텍스트 데이터로 변환하는 메소드
			data: JSON.stringify({"writer":writer,"content":content}),
			dataType: "text",
			success: function(result) {
				if(result=="success") {
					//신규 게시글을 입력받기 위한 태그 초기화
					$(".insert").val("");//입력태그 초기화
					$("#insertDiv").hide();//태그 숨김
					//
					//특정 페이지 번호의 게시글 목록을 출력하는 함수 호출
					boardListDisplay(page);
				}
			}, 
			error: function(xhr) {
				alert("에러코드(게시글 삽입) = "+xhr.status)
			}
		});
	});
	//
	//신규 게시글을 입력받기 위한 태그에서 [취소] 태그를 클릭한 경우 호출되는 이벤트 처리 함수
	$("#cancelInsertBtn").click(function() {
		//신규 게시글을 입력받기 위한 태그 초기화
		$(".insert").val("");//입력태그 초기화
		$("#insertDiv").hide();//태그 숨김
	});
	//
	//게시글의 [변경] 태그를 클릭한 경우 호출되는 이벤트 처리 함수
	//→ 글번호를 전달받아 RESTBOARD 테이블에 저장된 해당 글번호의 게시글을 검색하여 반환하는 페이지를 AJAX 기능으로 
	//	요청하여 처리결과를 JSON 형식의 데이터로 응답받아 변경 게시글을 입력받기 위한 태그의 입력값으로 초기화 처리
	function modify(num) {
		//alert(num);
		//
		//신규 게시글을 입력받기 위한 태그 초기화
		$(".insert").val("");//입력태그 초기화
		$("#insertDiv").hide();//태그 숨김
		//
		//변경 게시글을 입력받기 위한 태그 출력
		$("#updateDiv").show();
		//
		$.ajax({
			type: "get",
			//페이지 요청시 질의문자열(QueryString)을 사용하여 값 전달
			//→ 요청 처리 메소드의 매개변수에 @RequestParam 어노테이션을 사용하여 값을 제공받아 사용
			url: "${pageContext.request.contextPath}/board_view?num="+num,
			dataType: "json",
			success: function(result) {
				$("#updateNum").val(result.num);
				$("#updateWriter").val(result.writer);
				$("#updateContent").val(result.content);
			}, 
			error: function(xhr) {
				alert("에러코드(게시글 검색) = "+xhr.status)
			}
		});
	}
	//
	//변경 게시글을 입력받기 위한 태그에서 [변경] 태그를 클릭한 경우 호출되는 이벤트 처리 함수
	//→ 사용자 입력값을 얻어와 RESTBOARD 테이블에 저장된 게시글 변경하는 페이지를 AJAX 기능으로 요청하여 처리결과를 제공받아 응답 처리
	$("#updateBtn").click(function() {
		var num=$("#updateNum").val();
		var writer=$("#updateWriter").val();
		var content=$("#updateContent").val();
		//
		if(writer=="") {
			alert("작성자를 입력해 주세요.");
			return;
		}
		//
		if(content=="") {
			alert("내용 입력해 주세요.");
			return;
		}
		//
		$.ajax({
			type: "put",
			url: "${pageContext.request.contextPath}/board_modify",
			contentType: "application/json",
			data: JSON.stringify({"num":num,"writer":writer,"content":content}),
			dataType: "text",
			success: function(result) {
				if(result=="success") {
					//변경 게시글을 입력받기 위한 태그 초기화
					$(".update").val("");//입력태그 초기화
					$("#updateDiv").hide();//태그 숨김
					//
					//특정 페이지 번호의 게시글 목록을 출력하는 함수 호출
					boardListDisplay(page);
				}
			}, 
			error: function(xhr) {
				alert("에러코드(게시글 변경) = "+xhr.status)
			}
		});
	});
	//
	//변경 게시글을 입력받기 위한 태그에서 [취소] 태그를 클릭한 경우 호출되는 이벤트 처리 함수
	$("#cancelUpdateBtn").click(function() {
		//변경 게시글을 입력받기 위한 태그 초기화
		$(".update").val("");//입력태그 초기화
		$("#updateDiv").hide();//태그 숨김
	});
	//게시글의 [삭제] 태그를 클릭한 경우 호출되는 이벤트 처리 함수
	//→ 글번호를 전달받아 RESTBOARD 테이블에 저장된 해당 글번호의 게시글을 삭제하는 페이지를 AJAX 기능으로 요청하여 처리결과를 일반 텍스트로 제공받아 응답 처리 
	function remove(num) {
		//alert(num);
		//
		if(confirm("게시글을 삭제 하시겠습니까?")) {
			$.ajax({
				type: "delete",
				//페이지 요청시 요청 URL 주소를 사용하여 값 전달
				//→ 요청 처리 메소드의 매개변수에 @PathVariable 어노테이션을 사용하여 값을 제공받아 사용
				url: "${pageContext.request.contextPath}/board_remove/"+num,
				dataType: "text",
				success: function(result) {
					if(result=="success") {
						//특정 페이지 번호의 게시글 목록을 출력하는 함수 호출
						boardListDisplay(page);
					}
				}, 
				error: function(xhr) {
					alert("에러코드(게시글 삭제) = "+xhr.status)
				}
			});
		}
	}
	</script>
</body>
</html>

🐧REST API 테스트 프로그램 사용법

1. 구글에 Advanced REST Client 검색

2. Chrome 추가 버튼 클릭

3. 앱 추가 클릭

4. ARC 클릭

5. 무시하고 열기 클릭

6. 프로그램 사용

0개의 댓글