Spring(Intelli J 활용) - Rest(비동기) 구현

songmin jeon·2024년 3월 19일
0


레스트 방식으로 데이터 처리하기

  • 라우터 역활을 해주는 컨트롤러를 만듬.

  • JSON 데이터를 처리해줄 컨트롤러 필요

  • views에 rest 폴더 생성 > list.jsp 붙여녛기

  • 외부에 js 파일 생성하기

    • webapp/resources/js 폴더 생성
    • BoardUIController 컨트롤러 생성
    • boardList.js 생성

▶ BoardUIController.java

package org.example.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/rest")
public class BoardUIController { // View로 이동해주는 컨트롤러(Router 역활 - React.js)
    // 라우터 역활하는 컨트롤러를 만든다는 개념

    //http://localhost:8081/myweb/rest/list
    // 게시판 리스트 보기
    @GetMapping("/list")
    public String list(){
        // DB에서 데이터를 가져오기 -> View
        return "rest/list";
    }
}

▶ boardList.js 코드

function boardList(){
    // 서버통신 : ajax -> jQuery(X)
    // fetch().then().then()
    fetch("http://localhost:8081/myweb/api/board")
    // 위 경로 결과를 then()이 받는다.
    .then(function(res){ // res -> JSON String
        // ok는 이메일을 가르키는 단어
        if(!res.ok){
            throw new Error("Network response was not ok");
        }
        console.log(res);
        return res.json(); // JavaScript Object 변경
    })
    // res를 받아서 동적뷰를 만들어 낸다.
    .then(function(boards){
        console.log(boards);
        let boardListTable = document.getElementById("boardList");
        let tbody = boardListTable.querySelector("tbody");
        tbody.innerHTML = '';
        boards.forEach(function(board){
            let tr = document.createElement("tr"); // <tr></tr>
            tr.innerHTML =  '<td>' + board.num + '</td>' +
                            '<td>' + board.title + '</td>' +
                            '<td>' + board.writer + '</td>' +
                            '<td>' + board.indate + '</td>' +
                            '<td>' + board.cnt + '</td>' ;
            tbody.append(tr);
        });
    });
}
  • list.jsp
    • JSTL의 forEach가 없어도 게시판 리스트를 구현할 수 있다.
      (여기에 게시판 리스트를 출력(js이용)! 영역 참조.)
<%@ page contentType="text/html;charset=UTF-8" language="java"  pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<c:set var="cpath" value="<%=request.getContextPath() %>" />
<!DOCTYPE html>
<html lang="en">
<head>
  <title>Bootstrap Example</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css">
  <script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script>

  <script src="${cpath}/resources/js/boardList.js"></script>

<script>
 boardList(); // javascript 호출
</script>

</head>
<body>

<div class="container">
  <h2>Spring Web MVC</h2>
  <div class="card">
    <div class="card-header">BOARD</div>
    <div class="card-body">
          <table id="boardList" class="table table-hover">
            <thead>
              <tr>
                <th>번호</th>
                <th>제목</th>
                <th>작성자</th>
                <th>작성일</th>
                <th>조회수</th>
              </tr>
            </thead>
            <tbody>
            
              <!-- 여기에 게시판 리스트를 출력(js이용)! -->
              
            </tbody>
          </table>
          <button class="btn btn-primary btn-sm" onClick="location.href='${cpath}/register'">글쓰기</button>
    </div>
    <div class="card-footer">클라우드기반 인공지능 서비스 엔지니어링 과정(전송민)</div>
  </div>
</div>

</body>
</html>

rest로 글쓰기 기능 구현

  • BoardUIController 에 글쓰기 추가
    @GetMapping("/register")
    public String register(){
        return "rest/register"; // register.jsp
    }

  • /views/rest/의 경로에 register.jsp 복붙하여 넣기
    • 코드 다음과 같이 변경( js연결 및 버튼 타입으로 변경 )
<%@ page contentType="text/html;charset=UTF-8" language="java"  pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<c:set var="cpath" value="<%=request.getContextPath() %>" />
<!DOCTYPE html>
<html lang="en">
<head>
  <title>Bootstrap Example</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css">
  <script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script>

  <script src="${cpath}/resources/js/register.js"></script>

</head>
<body>
<div class="container">
  <h2>Spring Web MVC</h2>
  <div class="card">
    <div class="card-header">BOARD</div>
    <div class="card-body">

    <form>
      <div class="form-group">
        <label for="title">제목:</label>
        <input type="text" class="form-control" placeholder="Enter title" id="title" name="title">
      </div>
      <div class="form-group">
        <label for="content">내용:</label>
        <textarea rows="10" class="form-control" id="content" name="content"></textarea>
      </div>
      <div class="form-group">
        <label for="writer">작성자:</label>
        <input type="text" class="form-control" placeholder="Enter writer" id="writer" name="writer">
      </div>
      <button type="button" class="btn btn-primary btn-sm" onClick="goRegister()">등록</button>
      <button type="reset" class="btn btn-danger btn-sm">취소</button>
    </form>

    </div>
    <div class="card-footer">클라우드기반 인공지능 서비스 엔지니어링 과정(전송민)</div>
  </div>
</div>
</body>
</html>

  • register.js 작성
// 등록 버튼 클릭시 호출되는 함수
function goRegister(){
    // title, content, writer 값 가져오기
    let title = document.getElementById("title").value;
    let content = document.getElementById("content").value;
    let writer = document.getElementById("writer").value;
    //JavaScript Object -> JSON 변환
    let obj = {
        title : title
        , content : content
        , writer : writer
    };
    // POST(url, data(JSON), MIME Type)
    fetch("http://localhost:8081/myweb/api/board", {
        method : "POST"
        , headers : {
            'Content-Type':'application/json'
         }
        , body : JSON.stringify(obj)
     })
    .then(function(res){
        if(!res.ok){
            throw new Error("Network response was not ok");
        }
        // 등록이 성공 후에는 다시 리스트 페이지로...
        location.href = "/myweb/rest/list";
    })

    .catch(function(error){
        console.log(error);
    });
}

rest로 페이지 상세보기 구현

  • 상세보기 테이블을 get.js 로 구현.
function getBoardDetail(num){
      // 상세보기
      fetch("http://localhost:8081/myweb/api/board/"+num)
      .then(function(res){
         if(!res.ok){
             throw new Error("Network response was not ok");
          }
          return res.json(); // JSON
       })
      .then(function(board){
          // 상세보기 UI 동적으로 만들기(HTML - table)
          let boardTable=`
              <table class="table table-bordered">
                <tr>
                    <td>번호</td>
                    <td>${board.num}</td>
                </tr>
                <tr>
                    <td>제목</td>
                    <td>${board.title}</td>
                </tr>
                <tr>
                    <td>내용</td>
                    <td>${board.content}</td>
                </tr>
                <tr>
                    <td>작성자</td>
                    <td>${board.writer}</td>
                </tr>
                <tr>
                    <td>조회수</td>
                    <td>${board.cnt}</td>
                </tr>
              </table>
              <button type="button" class="btn btn-primary btn-sm"token interpolation">${board.num})">수정</button>
              <button type="button" class="btn btn-danger btn-sm"token interpolation">${board.num})">삭제</button>
              <button type="button" class="btn btn-info btn-sm">목록</button>
           `;
           document.getElementById("getDetail").innerHTML=boardTable;
       })
      .catch(function(error){
           console.log(error);
      });
 }

  • get.jsp 복붙
<%@ page contentType="text/html;charset=UTF-8" language="java"  pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<c:set var="cpath" value="<%=request.getContextPath() %>" />
<% pageContext.setAttribute("newLine","\n"); %>

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Bootstrap Example</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css">
  <script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script>

  <script src="${cpath}/resources/js/get.js"></script>

<script>
    getBoardDetail("${num}");
</script>

</head>
<body>

<div class="container">
  <h2>Spring Web MVC</h2>
  <div class="card">
    <div class="card-header">BOARD</div>
    <div class="card-body" id="getDetail">

        <!-- 상세보기 -->

    </div>
    <div class="card-footer">클라우드기반 인공지능 서비스 엔지니어링 과정(전송민)</div>
  </div>
</div>

</body>
</html>
  • get.js 생성
function getBoardDetail(num){
      // 상세보기
      fetch("http://localhost:8081/myweb/api/board/"+num)
      .then(function(res){
         if(!res.ok){
             throw new Error("Network response was not ok");
          }
          return res.json(); // JSON
       })
      .then(function(board){
          // 상세보기 UI 동적으로 만들기(HTML - table)
          let boardTable=`
              <table class="table table-bordered">
                <tr>
                    <td>번호</td>
                    <td>${board.num}</td>
                </tr>
                <tr>
                    <td>제목</td>
                    <td>${board.title}</td>
                </tr>
                <tr>
                    <td>내용</td>
                    <td>${board.content}</td>
                </tr>
                <tr>
                    <td>작성자</td>
                    <td>${board.writer}</td>
                </tr>
                <tr>
                    <td>조회수</td>
                    <td>${board.cnt}</td>
                </tr>
              </table>
              <button type="button" class="btn btn-primary btn-sm"token interpolation">${board.num})">수정</button>
              <button type="button" class="btn btn-danger btn-sm"token interpolation">${board.num})">삭제</button>
              <button type="button" class="btn btn-info btn-sm">목록</button>
           `;
           document.getElementById("getDetail").innerHTML=boardTable;
       })
      .catch(function(error){
           console.log(error);
      });
 }

rest로 게시글 삭제 구현

  • get.js 코드 중 삭제 버튼에 추가

onClick="goDelete(${board.num})"

  • get.js 코드 추가
 function goDelete(num){
    let deleteUrl = "http://localhost:8081/myweb/api/board/" + num;
    fetch(deleteUrl,{
        method : "DELETE"
    })
    .then(function(res){
        if(!res.ok){
            throw new Error("Network response was not ok");
        }
        location.href="/myweb/rest/list";
    })
    .catch(function(error){
        console.log(error);
    });
 }

rest로 게시글 수정 구현

  • get.js 코드 중 수정 버튼에 onclick 추가

    onClick="goUpdateGet(${board.num})"

  • get.js 코드 추가
 function goUpdateGet(num){
    location.href="/myweb/rest/update/"+num; // RouterController

 }
  • BoardUIController 에서 업데이터 매서드 생성
    @GetMapping("/update/{num}")
    public String updateGet(@PathVariable Long num, Model model){
        model.addAttribute("num", num);
        return "rest/update"; // update.jsp
  • update.js 생성
// 업데이트 화면을 구성하는 코드
function updateDetail(num){
    fetch("http://localhost:8081/myweb/api/board/"+num)
    .then(function(res){
          return res.json();
     })
    .then(function(board){
           let updateFrom=`
             <form>
                 <input type="hidden" name="num" value="${board.num}" id="num"/>
                  <table class="table table-bordered">
                     <tr>
                       <td>번호</td>
                       <td>${board.num}</td>
                     </tr>
                     <tr>
                        <td>제목</td>
                        <td><input type="text" class="form-control" id="title" name="title" value="${board.title}"/></td>
                      </tr>
                      <tr>
                         <td>내용</td>
                         <td><textarea rows="10" class="form-control" id="content" name="content">${board.content}</textarea></td>
                       </tr>
                  </table>
                  <button type="button" class="btn btn-sm btn-primary"token interpolation">${board.num})">수정</button>
                  <button type="reset" class="btn btn-sm btn-danger">취소</button>
                  <button type="button" class="btn btn-sm btn-info">목록</button>
             </form>
            `;
            document.getElementById("updateForm").innerHTML=updateFrom;
     })
    .catch(function(error){
         console.log(error);
      });
}

// 수정한 내용 업데이트 코드
function goUpdatePost(num){
    let num =  parseInt(document.getElementById("num").value);
    let title = document.getElementById("title").value;
    let content = document.getElementById("content").value;

    let updateData = {
        num : num
        , title : title
        , content : content
    }

    // 수정하기(POST)
    fetch("http://localhost:8081/myweb/api/board/" + num, {
        method : "PUT"
        , headers : {
            "Content-Type" : "application/json"
        }
        , body : JSON.stringify(updateData)
    })
    .then(function(res){
        if(!res.ok){
            throw new Error("Network response was not ok");
        }
        location.href = "/myweb/rest/list";
    })
    .catch(function(error){
        console.log(error);
    });
}
profile
제가 한 번 해보겠습니다.

0개의 댓글