static 안에 저거 혼자 있으면 SPA (Single Page Application)가 된다.


package com.jeungsu.silver.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.jeungsu.silver.service.SujinService;
import com.jeungsu.silver.vo.SujinVO;
import lombok.extern.slf4j.Slf4j;
// Restful api 구현
@RestController
@RequestMapping("/api")
@Slf4j
public class SujinController {
// 컨트롤러는 서비스를 부름
@Autowired
private SujinService sujinService;
// 리스트 조회
@GetMapping(value="/sujins", produces = "application/json;charset=utf-8")
public List<SujinVO> sujinList(){
return sujinService.sujinList();
}
// 한개 조회
@GetMapping(value="/sujin/{num}", produces = "application/json;charset=utf-8")
public SujinVO sujinOne(@PathVariable("num") int sujinNum) {
return sujinService.sujinOne(sujinNum);
}
// 삽입
@PostMapping(value="/sujin", produces = "application/json;charset=utf-8")
public int sujinInsert(@RequestBody SujinVO sujinVO) {
return sujinService.sujinInsert(sujinVO);
}
// 수정
@PutMapping(value="/sujin", produces = "application/json;charset=utf-8")
public int sujinUpdate(@RequestBody SujinVO sujinVO) {
return sujinService.sujinUpdate(sujinVO);
}
// 삭제
@DeleteMapping(value="/sujin/{num}", produces = "application/json;charset=utf-8")
public int sujinDelete(@PathVariable("num") int sujinNum) {
return sujinService.sujinDelete(sujinNum);
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style>
#list{
height:50vh;
overflow: scroll;
}
</style>
</head>
<body>
<h1>혼자있음 SPA(Single Page Application)</h1>
<div id="list"></div>
<div id="gitae">
<form action="">
번호 <input type="text" name="sujinNum" value=""><br>
이름 <input type="text" name="sujinName" value=""><br>
내용 <input type="text" name="sujinContent" value=""><br>
<input type="button" onclick="fInsert()" value="입력">
<input type="button" onclick="fUpdate()" value="수정">
<input type="button" onclick="fDel()" value="삭제">
</form>
</div>
<script>
// Sujin 삭제
function fDel(){
let sujinNum = myForm.sujinNum.value;
let xhr = new XMLHttpRequest();
xhr.open("delete", `/api/sujin/${sujinNum}`, true);
xhr.setRequestHeader("Content-Type", "application/json;charset=utf-8");
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
if(xhr.responseText != 0){
alert("서버에서 잘 처리 완료");
fList(); // 일단 간단하게 다시 리스트를 부르는 걸로
// 실제는 tr만 추가적으로 붙여주는 것이 효율적
}
}
}
xhr.send();
}
// Sujin 수정
function fUpdate(){
let data = {
sujinNum:myForm.sujinNum.value,
sujinName:myForm.sujinName.value,
sujinContent:myForm.sujinContent.value
}
let xhr = new XMLHttpRequest();
xhr.open("put", `/api/sujin`, true);
xhr.setRequestHeader("Content-Type", "application/json;charset=utf-8");
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
if(xhr.responseText != 0){
alert("서버에서 잘 처리 완료");
fList(); // 일단 간단하게 다시 리스트를 부르는 걸로
// 실제는 tr만 추가적으로 붙여주는 것이 효율적
}
}
}
xhr.send(JSON.stringify(data));
}
// Sujin 넣기
function fInsert(){
// 개발시에는 넘기는 data가 눈에 잘 들어오게 하는 게 디버깅에 효율적
let data = {
sujinName:myForm.sujinName.value,
sujinContent:myForm.sujinContent.value
}
let xhr = new XMLHttpRequest();
xhr.open("post", `/api/sujin`, true);
xhr.setRequestHeader("Content-Type", "application/json;charset=utf-8");
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
if(xhr.responseText != 0){
alert("서버에서 잘 처리 완료");
fList(); // 일단 간단하게 다시 리스트를 부르는 걸로
// 실제는 tr만 추가적으로 붙여주는 것이 효율적
}
}
}
xhr.send(JSON.stringify(data));
}
const myList = document.querySelector("#list")
// 리스트 출력함수
function fList(){
let xhr = new XMLHttpRequest();
xhr.open("get", "/api/sujins", true);
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
let dataList = JSON.parse(xhr.responseText);
let tblStr = "<table border=1>"
tblStr += "<tr><th>넘버</th><th>이름</th><th>내용</th></tr>"
for(let i=0; i<dataList.length; i++){
tblStr += "<tr>";
tblStr += `<td><a href="#" onclick="fOne('${dataList[i].sujinNum}')">${dataList[i].sujinNum}</a></td>`
tblStr += `<td>${dataList[i].sujinName}</td>`
tblStr += `<td>${dataList[i].sujinContent}</td>`
tblStr += "</tr>";
}
tblStr += "</table>";
myList.innerHTML = tblStr;
}
}
xhr.send();
}
// Sujin 1개만 가져오기
const myForm = document.forms[0]
function fOne(pNum){
event.preventDefault(); // a 태그 내장기능 href로 이동하는 거 막기
let xhr = new XMLHttpRequest();
xhr.open("get", `/api/sujin/${pNum}`, true);
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
let sujinOne = JSON.parse(xhr.responseText);
myForm.sujinNum.value = sujinOne.sujinNum;
myForm.sujinName.value = sujinOne.sujinName;
myForm.sujinContent.value = sujinOne.sujinContent;
}
}
xhr.send();
}
window.addEventListener("DOMContentLoaded", fList);
</script>
</body>
</html>
