create table restboard(num number primary key, writer varchar2(50), content varchar2(100), regdate date);create sequence restboard_seq;
📃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; }
📃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을 사용 }
📃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); } }
📃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); } }
📃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"; } }
📢페이징 처리 관련 값을 필드에 저장하기 위한 클래스
📃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; } }
📃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>
1. 구글에 Advanced REST Client 검색
2. Chrome 추가 버튼 클릭
3. 앱 추가 클릭
4. ARC 클릭
5. 무시하고 열기 클릭
6. 프로그램 사용