개발자입니다
[비트캠프] 48일차(10주차3일) - Java: (backend, frontend)-app-03 본문
[비트캠프] 48일차(10주차3일) - Java: (backend, frontend)-app-03
끈기JK 2023. 1. 11. 10:33
postman
'postman' 검색 후 Windows 64-bit 다운로드
Collections > '게시글 REST API 테스트' 추가한다.
add new request 또는 우측 창 + 눌러서 요청을 추가한다.
POST(Create) : 게시글 등록은 POST 방식이며 주소 입력 후 Body에 보낼 데이터의 KEY : VALUE 입력하고 Send 한다.
그러면 아래에 응답 결과가 표시된다.
GET(Read) : 게시글 목록 조회
GET(Read) : 게시글 상세 조회
PUT(Update) : 게시글 변경
DELETE(Delete): 게시글 삭제
백엔드
HTTP 요청
① Query String 방식으로 데이터 보내기
브라우저가 URL을 cache에 보관 → 외부 노출 → 보안에 취약
② Message-body 방식으로 데이터 보내기
브라우저 cache에 보관하지 않는다 → 직접적인 외부 노출 방지
Query String 또는 Message Body의 no=1&name=aaa&... 를 SpringBoot가 obj.setNo(Integer.parseInt("1"), obj.setName("aaa"), ... 한다.
→ property(getter/setter)가 있는 항목만 get, set 글자 빼고 맨 앞글자 소문자로 만들어서 들어온 값을 Member 인스턴스 필드에 저장한다. field가 있어도 property가 없으면 저장하지 않는다.
class Member { - } 에서 field는 int no, string name, ... 등이다.
property(getter/setter)는 getNo(), setNo(), getTel(), ... 등이다.
get만 있으면 read only, set만 있으면 write only가 된다.
backend-app 소스
MemberController.java
package bitcamp.bootapp.controller;
import java.sql.Date;
import java.util.HashMap;
import java.util.Map;
import org.springframework.web.bind.annotation.CrossOrigin;
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.RestController;
import bitcamp.bootapp.dao.MemberDao;
import bitcamp.bootapp.vo.Member;
@CrossOrigin(origins = {"http://127.0.0.1:5500", "http://localhost:5500"})
@RestController
public class MemberController {
MemberDao memberDao = new MemberDao();
@PostMapping("/members")
public Object addMember(
String name,
String tel,
String postNo,
String basicAddress,
String detailAddress,
boolean working, // ..&working=xxx&.. => 파라미터가 있으면 true, 없으면 false,
// "on"=true/"off"=false, "1"=true/"0"=false, 그 밖에 문자열은 변환 오류 발생!
char gender, // ..&gender=M&.. => 문자 1개의 문자열 변환, null 또는 그 밖에 문자열은 변환 오류 발생!
byte level // ..&level=1&.. => Byte.parseByte("1") => 1, null 또는 byte 범위를 초과하는 숫자는 변환 오류 발생
) {
//@RequestParam(name = "name", required = false) String name 로도 가능
// String title 로 @를 생략할 수 있다.
System.out.printf("%s,%s,%s,%s,%s,%b,%c,%d\n",
name, tel, postNo, basicAddress, detailAddress, working, gender, level);
Member m = new Member();
m.setName(name);
m.setTel(tel);
m.setPostNo(postNo);
m.setBasicAddress(basicAddress);
m.setDetailAddress(detailAddress);
m.setWorking(working);
m.setGender(gender);
m.setLevel(level);
m.setCreatedDate(new Date(System.currentTimeMillis()).toString());
this.memberDao.insert(m);
Map<String, Object> contentMap = new HashMap<>();
contentMap.put("status", "success");
return contentMap;
}
@GetMapping("/members")
public Object getMembers() {
Member[] members = this.memberDao.findAll();
Map<String, Object> contentMap = new HashMap<>();
contentMap.put("status", "success");
contentMap.put("data", members);
return contentMap;
}
@GetMapping("/members/{memberNo}")
public Object getMember(@PathVariable int memberNo) {
Member m = this.memberDao.findByNo(memberNo);
Map<String, Object> contentMap = new HashMap<>();
if (m == null) {
contentMap.put("status", "failure");
contentMap.put("message", "해당 번호의 회원이 없습니다.");
} else {
contentMap.put("status", "success");
contentMap.put("data", m);
}
return contentMap;
}
@PutMapping("/members/{No}") // No 가 Member 클래스의 프로퍼티로 있으면 member 에서 받을 수 있다.
public Object updateMember(
// @PathVariable int memberNo, // Member 인스턴스로 직접 받을 수 있다.
Member member) {
Map<String, Object> contentMap = new HashMap<>();
Member old = this.memberDao.findByNo(member.getNo());
if (old == null) {
contentMap.put("status", "failure");
contentMap.put("data", "회원이 없습니다.");
return contentMap;
}
member.setCreatedDate(old.getCreatedDate());
this.memberDao.update(member);
contentMap.put("status", "success");
return contentMap;
}
@DeleteMapping("/members/{memberNo}")
public Object deleteMember(
// 낱개로 받을 때는 @PathVariable 애노테이션을 생략하면 안된다.
@PathVariable int memberNo) {
Member m = this.memberDao.findByNo(memberNo);
Map<String, Object> contentMap = new HashMap<>();
if (m == null) {
contentMap.put("status", "failure");
contentMap.put("message", "회원이 없습니다.");
} else {
this.memberDao.delete(m);
contentMap.put("status", "success");
}
return contentMap;
}
}
frontend-app 소스
list.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>회원</h1>
<a href="form.html">새 회원</a>
<table border="1">
<thead>
<tr>
<th>번호</th>
<th>이름</th>
<th>전화</th>
<th>재직</th>
<th>전공</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script>
var tbody = document.querySelector('tbody');
function getLevelTitle(level) {
switch (level) {
case 0: return "비전공자";
case 1: return "준전공자";
case 2: return "전공자";
default: return "";
}
}
fetch('http://localhost:8080/members')
// method: 생략하면 GET 요청이다.
.then((response) => { return response.json(); })
.then((obj) => {
var html = '';
for(var m of obj.data) {
html += `<tr>
<td>${m.no}</td>
<td><a href="view.html?no=${m.no}">${m.name} </a></td>
<td>${m.tel}</td>
<td>${m.working ? "예" : "아니오"}</td>
<td>${getLevelTitle(m.level)}</td>
</tr>\n`;
}
tbody.innerHTML = html;
})
.catch(() => {
alert("서버 요청 오류!")
console.log(err);
});
</script>
</body>
</html>
form.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>새 회원</h1>
<form>
<table border="1">
<tbody>
<tr>
<th>이름</th>
<td><input type="text" name="name" id="f-name"></td>
</tr>
<tr>
<th>전화</th>
<td><input type="text" name="tel" id="f-tel"></td>
</tr>
<tr>
<th>우편번호</th>
<td><input type="text" name="postNo" id="f-postNo"></td>
</tr>
<tr>
<th>기본주소</th>
<td><input type="text" name="basicAddress" id="f-basicAddress"></td>
</tr>
<tr>
<th>상세주소</th>
<td><input type="text" name="detailAddress" id="f-detailAddress"></td>
</tr>
<tr>
<th>재직여부</th>
<td>
<input type="checkbox" name="working" value="true" id="f-working"> 재직중
</td>
</tr>
<tr>
<th>성별</th>
<td>
<input type="radio" name="gender" value="W" id="f-gender-w" checked> 여성
<input type="radio" name="gender" value="M" id="f-gender-m"> 남성
</td>
</tr>
<tr>
<th>전공</th>
<td>
<select name="level" id="f-level">
<option value="0">비전공자</option>
<option value="1">준전공자</option>
<option value="2">전공자</option>
</select>
</td>
</tr>
</tbody>
</table>
<button id="add-btn" type="button">등록</button>
<button id="cancel-btn" type="button">취소</button>
</form>
<script>
document.querySelector('#add-btn').onclick = (e) => {
var name = encodeURIComponent(document.querySelector('#f-name').value);
var tel = document.querySelector('#f-tel').value;
var postNo = document.querySelector('#f-postNo').value;
var basicAddress = encodeURIComponent(document.querySelector('#f-basicAddress').value);
var detailAddress = encodeURIComponent(document.querySelector('#f-detailAddress').value);
var working = document.querySelector('#f-working').checked;
var gender = document.querySelector('#f-gender-w').checked ? 'W' : 'M';
var level = document.querySelector('#f-level').value;
// console.log(`name=${name}&tel=${tel}&postNo=${postNo}&basicAddress=${basicAddress}`
// +`&detailAddress=${detailAddress}&working=${working}&gender=${gender}&level=${level}`);
fetch('http://localhost:8080/members', {
method: 'POST',
headers: {
'Content-type': 'application/x-www-form-urlencoded'
},
body: `name=${name}&tel=${tel}&postNo=${postNo}&basicAddress=${basicAddress}`
+ `&detailAddress=${detailAddress}&working=${working}&gender=${gender}&level=${level}`
})
.then((response) => response.json())
.then((obj) => {
location.href = "list.html";
})
.catch(() => {
alert("서버 요청 오류!")
console.log(err);
});
};
document.querySelector('#cancel-btn').onclick = (e) => {
location.href = "list.html";
}
</script>
</body>
</html>
view.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>회원</h1>
<form>
<table border="1">
<tbody>
<tr>
<th>번호</th>
<td><input type="text" name="no" id="f-no" readonly></td>
</tr>
<tr>
<th>이름</th>
<td><input type="text" name="name" id="f-name"></td>
</tr>
<tr>
<th>전화</th>
<td><input type="text" name="tel" id="f-tel"></td>
</tr>
<tr>
<th>우편번호</th>
<td><input type="text" name="postNo" id="f-postNo"></td>
</tr>
<tr>
<th>기본주소</th>
<td><input type="text" name="basicAddress" id="f-basicAddress"></td>
</tr>
<tr>
<th>상세주소</th>
<td><input type="text" name="detailAddress" id="f-detailAddress"></td>
</tr>
<tr>
<th>재직여부</th>
<td>
<input type="checkbox" name="working" value="true" id="f-working"> 재직중
</td>
</tr>
<tr>
<th>성별</th>
<td>
<input type="radio" name="gender" value="W" id="f-gender-w" checked> 여성
<input type="radio" name="gender" value="M" id="f-gender-m"> 남성
</td>
</tr>
<tr>
<th>전공</th>
<td>
<select name="level" id="f-level">
<option value="0">비전공자</option>
<option value="1">준전공자</option>
<option value="2">전공자</option>
</select>
</td>
</tr>
<th>등록일</th>
<td><span id="f-createdDate"></span></td>
</tr>
</tbody>
</table>
<button id="update-btn" type="button">변경</button>
<button id="delete-btn" type="button">삭제</button>
<button id="list-btn" type="button">목록</button>
</form>
<script>
var values = location.href.split("?");
if (values.length != 2) {
alert("올바른 페이지 주소가 아닙니다.")
throw "no 파라미터 값이 누락되었습니다.";
}
var values2 = values[1].split("=");
if (values2.length != 2 || values2[0] != "no") {
alert("올바른 페이지 주소가 아닙니다.")
throw "no 파라미터 값이 누락되었습니다.";
}
var no = parseInt(values2[1]);
if (isNaN(no)) {
alert("게시글 번호가 옳지 않습니다.")
throw "no 파라미터 값이 숫자가 아닙니다.";
}
fetch(`http://localhost:8080/members/${no}`)
.then((response) => response.json())
.then((obj) => {
if (obj.status == "failure") {
alert("서버 요청 오류!");
console.log(obj.data);
return;
}
document.querySelector('#f-no').value = obj.data.no;
document.querySelector('#f-name').value = obj.data.name;
document.querySelector('#f-tel').value = obj.data.tel;
document.querySelector('#f-postNo').value = obj.data.postNo;
document.querySelector('#f-basicAddress').value = obj.data.basicAddress;
document.querySelector('#f-detailAddress').value = obj.data.detailAddress;
document.querySelector('#f-working').checked = obj.data.working;
if (obj.data.gender == 'W') {
document.querySelector('#f-gender-w').checked = true;
} else {
document.querySelector('#f-gender-m').checked = true;
}
document.querySelector('#f-level').value = obj.data.level;
document.querySelector('#f-createdDate').innerHTML = obj.data.createdDate;
})
.catch((err) => {
alert("서버 요청 오류!");
console.log(err)
});
document.querySelector('#update-btn').onclick = (e) => {
var name = encodeURIComponent(document.querySelector('#f-name').value);
var tel = document.querySelector('#f-tel').value;
var postNo = document.querySelector('#f-postNo').value;
var basicAddress = encodeURIComponent(document.querySelector('#f-basicAddress').value);
var detailAddress = encodeURIComponent(document.querySelector('#f-detailAddress').value);
var working = document.querySelector('#f-working').checked;
var gender = document.querySelector('#f-gender-w').checked ? 'W' : 'M';
var level = document.querySelector('#f-level').value;
fetch(`http://localhost:8080/members/${no}`, {
method: 'PUT',
headers: {
'Content-type': 'application/x-www-form-urlencoded'
},
body: `name=${name}&tel=${tel}&postNo=${postNo}&basicAddress=${basicAddress}`
+ `&detailAddress=${detailAddress}&working=${working}&gender=${gender}&level=${level}`
})
.then((response) => response.json())
.then((obj) => {
if (obj.status == "failure"){
alert("회원 변경 오류!\n" + obj.data);
console.log(obj.data);
return;
}
location.href = "list.html";
})
.catch(() => {
alert("서버 요청 오류!")
console.log(err);
});
};
document.querySelector('#delete-btn').onclick = (e) => {
fetch(`http://localhost:8080/members/${no}`, {
method: 'DELETE'
})
.then((response) => response.json())
.then((obj) => {
if (obj.status == "failure") {
alert("회원 삭제 오류!\n" + obj.data);
console.log(obj.data);
return;
}
location.href = "list.html";
})
.catch(() => {
alert("서버 요청 오류!")
console.log(err);
});
}
document.querySelector('#list-btn').onclick = (e) => {
location.href = "list.html";
}
</script>
</body>
</html>
03. 강사 관리 추가하기
backend-app 소스
TeacherController.java
package bitcamp.bootapp.controller;
import java.sql.Date;
import java.util.HashMap;
import java.util.Map;
import org.springframework.web.bind.annotation.CrossOrigin;
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.RestController;
import bitcamp.bootapp.dao.TeacherDao;
import bitcamp.bootapp.vo.Teacher;
@CrossOrigin(origins = {"http://127.0.0.1:5500", "http://localhost:5500"})
@RestController // @Controller 하면 return할때 json으로 변환하지 않는다.
public class TeacherController {
TeacherDao teacherDao = new TeacherDao();
@PostMapping("/teachers")
public Object addTeacher(Teacher teacher) {
teacher.setCreatedDate(new Date(System.currentTimeMillis()).toString());
this.teacherDao.insert(teacher);
Map<String,Object> contentMap = new HashMap<>();
contentMap.put("status", "success");
return contentMap;
}
@GetMapping("/teachers")
public Object getTeachers() {
Teacher[] teachers = this.teacherDao.findAll();
Map<String,Object> contentMap = new HashMap<>();
contentMap.put("status", "success");
contentMap.put("data", teachers);
return contentMap;
}
@GetMapping("/teachers/{no}")
public Object getTeacher(@PathVariable int no) {
Teacher b = this.teacherDao.findByNo(no);
Map<String,Object> contentMap = new HashMap<>();
if (b == null) {
contentMap.put("status", "failure");
contentMap.put("data", "강사가 없습니다.");
} else {
contentMap.put("status", "success");
contentMap.put("data", b);
}
return contentMap;
}
@PutMapping("/teachers/{no}")
public Object updateTeacher(Teacher teacher) {
Map<String,Object> contentMap = new HashMap<>();
Teacher old = this.teacherDao.findByNo(teacher.getNo());
if (old == null) {
contentMap.put("status", "failure");
contentMap.put("data", "강사가 없습니다.");
return contentMap;
}
teacher.setCreatedDate(old.getCreatedDate());
this.teacherDao.update(teacher);
contentMap.put("status", "success");
return contentMap;
}
@DeleteMapping("/teachers/{no}")
public Object deleteTeacher(@PathVariable int no) {
Teacher m = this.teacherDao.findByNo(no);
Map<String,Object> contentMap = new HashMap<>();
if (m == null) {
contentMap.put("status", "failure");
contentMap.put("data", "강사가 없습니다.");
} else {
this.teacherDao.delete(m);
contentMap.put("status", "success");
}
return contentMap;
}
}
TeacherDao.java
package bitcamp.bootapp.dao;
import java.util.Arrays;
import bitcamp.bootapp.vo.Teacher;
public class TeacherDao {
private static final int SIZE = 100;
private int no;
private int count;
private Teacher[] teachers = new Teacher[SIZE];
public void insert(Teacher teacher) {
teacher.setNo(++no);
this.teachers[this.count++] = teacher;
}
public Teacher[] findAll() {
return Arrays.copyOf(teachers, count);
}
public Teacher findByNo(int no) {
for (int i = 0; i < this.count; i++) {
if (this.teachers[i].getNo() == no) {
return this.teachers[i];
}
}
return null;
}
public void update(Teacher teacher) {
this.teachers[this.indexOf(teacher)] = teacher;
}
public void delete(Teacher teacher) {
for (int i = this.indexOf(teacher) + 1; i < this.count; i++) {
this.teachers[i - 1] = this.teachers[i];
}
this.teachers[--this.count] = null; // 레퍼런스 카운트를 줄인다.
}
private int indexOf(Teacher teacher) {
for (int i = 0; i < this.count; i++) {
if (this.teachers[i].getNo() == teacher.getNo()) {
return i;
}
}
return -1;
}
}
Teacher.java
package bitcamp.bootapp.vo;
public class Teacher {
private int no;
private String name;
private String tel;
private String email;
private int degree;
private String school;
private String major;
private int wage;
private String createdDate;
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getDegree() {
return degree;
}
public void setDegree(int degree) {
this.degree = degree;
}
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
public String getMajor() {
return major;
}
public void setMajor(String major) {
this.major = major;
}
public int getWage() {
return wage;
}
public void setWage(int wage) {
this.wage = wage;
}
public String getCreatedDate() {
return createdDate;
}
public void setCreatedDate(String createdDate) {
this.createdDate = createdDate;
}
}
frontend-app 소스
list.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>강사</h1>
<a href="form.html">새 강사</a>
<table border="1">
<thead>
<tr>
<th>번호</th>
<th>이름</th>
<th>전화</th>
<th>학위</th>
<th>전공</th>
<th>시강료</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script>
var tbody = document.querySelector("tbody");
function getDegreeTitle(level) {
switch (level) {
case 1: return "고졸";
case 2: return "전문학사";
case 3: return "학사";
case 4: return "석사";
case 5: return "박사";
case 0: return "기타";
default: return "";
}
}
fetch('http://localhost:8080/teachers')
.then((response) => {return response.json();})
.then((obj) => {
var html = '';
for (var t of obj.data) {
html += `<tr>
<td>${t.no}</td>
<td><a href="view.html?no=${t.no}">${t.name} </a></td>
<td>${t.tel}</td>
<td>${getDegreeTitle(t.degree)}</td>
<td>${t.major}</td>
<td>${t.wage}</td>
</tr>\n`;
}
tbody.innerHTML = html;
})
.catch((err) => {
alert("서버 요청 오류!");
console.log(err);
});
</script>
</body>
</html>
form.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>새 강사</h1>
<form>
<table border="1">
<tbody>
<tr>
<th>이름</th>
<td><input type="text" name="name" id="f-name"></td>
</tr>
<tr>
<th>전화</th>
<td><input type="tel" name="tel" id="f-tel"></td>
</tr>
<tr>
<th>이메일</th>
<td><input type="email" name="email" id="f-email"></td>
</tr>
<tr>
<th>학위</th>
<td>
<select name="degree" id="f-degree">
<option value="1">고졸</option>
<option value="2">전문학사</option>
<option value="3" selected>학사</option>
<option value="4">석사</option>
<option value="5">박사</option>
<option value="0">기타</option>
</select>
</td>
</tr>
<tr>
<th>학교</th>
<td><input type="text" name="school" id="f-school"></td>
</tr>
<tr>
<th>전공</th>
<td><input type="text" name="major" id="f-major"></td>
</tr>
<tr>
<th>강의료</th>
<td><input type="number" name="wage" id="f-wage">원/시간</td>
</tr>
</tbody>
</table>
<button id="add-btn" type="button">등록</button>
<button id="cancel-btn" type="button">취소</button>
</form>
<script>
document.querySelector('#add-btn').onclick = (e) => {
var name = encodeURIComponent(document.querySelector('#f-name').value);
var tel = document.querySelector('#f-tel').value;
var email = document.querySelector('#f-email').value;
var degree = document.querySelector('#f-degree').value;
var school = encodeURIComponent(document.querySelector('#f-school').value);
var major = encodeURIComponent(document.querySelector('#f-major').value);;
var wage = document.querySelector('#f-wage').value;
// console.log(`name=${name}&tel=${tel}&email=${email}°ree=${degree}&school=${school}` +
// `&major=${major}&wage=${wage}`);
fetch('http://localhost:8080/teachers', {
method: 'POST',
headers: {
'Content-type': 'application/x-www-form-urlencoded'
},
body: `name=${name}&tel=${tel}&email=${email}°ree=${degree}&school=${school}` +
`&major=${major}&wage=${wage}`
})
.then((response) => {return response.json();})
.then((obj) => {
location.href = "list.html";
})
.catch((err) => {
alert("서버 요청 오류!");
console.log(err);
});
};
document.querySelector('#cancel-btn').onclick = (e) => {
location.href = "list.html";
};
</script>
</body>
</html>
view.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>회원</h1>
<form>
<table border="1">
<tbody>
<tr>
<th>번호</th>
<td><input type="text" name="no" id="f-no" readonly></td>
</tr>
<tr>
<th>이름</th>
<td><input type="text" name="name" id="f-name"></td>
</tr>
<tr>
<th>전화</th>
<td><input type="tel" name="tel" id="f-tel"></td>
</tr>
<tr>
<th>이메일</th>
<td><input type="email" name="email" id="f-email"></td>
</tr>
<tr>
<th>학위</th>
<td>
<select name="degree" id="f-degree">
<option value="1">고졸</option>
<option value="2">전문학사</option>
<option value="3" selected>학사</option>
<option value="4">석사</option>
<option value="5">박사</option>
<option value="0">기타</option>
</select>
</td>
</tr>
<tr>
<th>학교</th>
<td><input type="text" name="school" id="f-school"></td>
</tr>
<tr>
<th>전공</th>
<td><input type="text" name="major" id="f-major"></td>
</tr>
<tr>
<th>강의료</th>
<td><input type="number" name="wage" id="f-wage">원/시간</td>
</tr>
<tr>
<th>등록일</th>
<td><span id="f-createdDate"></span></td>
</tr>
</tbody>
</table>
<button id="update-btn" type="button">변경</button>
<button id="delete-btn" type="button">삭제</button>
<button id="list-btn" type="button">목록</button>
</form>
<script>
var values = location.href.split('?');
if (values.length != 2) {
alert("옳바른 페이지 주소가 아닙니다.");
throw "no 파라미터 값이 누락되었습니다.";
}
var values2 = values[1].split("=");
if (values2.length != 2 || values2[0] != "no") {
alert("옳바른 페이지 주소가 아닙니다.");
throw "no 파라미터 값이 누락되었습니다.";
}
var no = parseInt(values2[1]);
if (isNaN(no)) {
alert("강사 번호가 옳지 않습니다.");
throw "no 파라미터 값이 숫자가 아닙니다.";
}
fetch(`http://localhost:8080/teachers/${no}`)
.then((response) => response.json())
.then((obj) => {
if (obj.status == "failure") {
alert("서버 요청 오류!");
console.log(obj.data);
return;
}
document.querySelector("#f-no").value = obj.data.no;
document.querySelector("#f-name").value = obj.data.name;
document.querySelector("#f-tel").value = obj.data.tel;
document.querySelector("#f-email").value = obj.data.email;
document.querySelector("#f-degree").value = obj.data.degree;
document.querySelector("#f-school").value = obj.data.school;
document.querySelector("#f-major").value = obj.data.major;
document.querySelector("#f-wage").value = obj.data.wage;
document.querySelector("#f-createdDate").innerHTML = obj.data.createdDate;
})
.catch((err) => {
alert("서버 요청 오류!");
console.log(err)
});
document.querySelector('#update-btn').onclick = (e) => {
var name = encodeURIComponent(document.querySelector('#f-name').value);
var tel = document.querySelector('#f-tel').value;
var email = document.querySelector('#f-email').value;
var degree = document.querySelector('#f-degree').value;
var school = encodeURIComponent(document.querySelector('#f-school').value);
var major = encodeURIComponent(document.querySelector('#f-major').value);;
var wage = document.querySelector('#f-wage').value;
fetch(`http://localhost:8080/teachers/${no}`, {
method: 'PUT',
headers: {
'Content-type': 'application/x-www-form-urlencoded'
},
body: `name=${name}&tel=${tel}&email=${email}°ree=${degree}&school=${school}` +
`&major=${major}&wage=${wage}`
})
.then((response) => response.json())
.then((obj) => {
if (obj.status == "failure") {
alert("강사 변경 오류!\n" + obj.data);
return;
}
location.href = "list.html";
})
.catch((err) => {
alert("서버 요청 오류!");
console.log(err);
});
};
document.querySelector('#delete-btn').onclick = (e) => {
fetch(`http://localhost:8080/teachers/${no}`, {
method: 'DELETE'
})
.then((response) => response.json())
.then((obj) => {
if (obj.status == "failure") {
alert("강사 삭제 오류!\n" + obj.data);
return;
}
location.href = "list.html";
})
.catch((err) => {
alert("서버 요청 오류!");
console.log(err);
});
};
document.querySelector('#list-btn').onclick = (e) => {
location.href = "list.html";
};
</script>
</body>
</html>
조언
*100가지 기능을 다 알아야 취업하는 건 아니다. 자주 쓰는 기능을 잘 알아야한다.
과제
/
'네이버클라우드 AIaaS 개발자 양성과정 1기 > Java' 카테고리의 다른 글
[Java] 예제 소스 정리 - 상속, 추상 클래스 (0) | 2023.01.12 |
---|---|
[비트캠프] 49일차(10주차4일) - Java: (backend, frontend)-app-04~05, 상속, 생성자 (0) | 2023.01.12 |
[비트캠프] 47일차(10주차2일) - Java: (backend, frontend)-app-02 (0) | 2023.01.10 |
[비트캠프] 46일차(10주차1일) - Java(캡슐화, getter/setter, 접근 범위), app-11~13, backend-app-01~02 (0) | 2023.01.09 |
[Java] 예제 소스 정리 - 생성자 활용, 인스턴스 메서드와 클래스 메서드 활용 (0) | 2023.01.06 |