2021-12-13(월) 6주차 1일

Jeongyun Heo·2021년 12월 13일
0

처음부터 다시 해보기

index.html - mylist-boot/src/main/resources/static

ul 태그 지우기

static - contact 폴더 지우기

변수, 배열, 연산자, 제어문 활용 → 연락처 관리 구현하기

90-MyList프로젝트1.pdf / 1 페이지

Front-end
static/index.html
.index.html ← 연락처 메인화면 (연락처 목록 출력)
.form.html ← 연락처 입력화면
.view.html ← 연락처 상세보기 및 변경폼

Back-end
ContactController
.list() ← 목록 데이터 제공
.add() ← 연락처 입력 처리
.get() ← 연락처 상세 정보 제공
.update() ← 연락처 정보 변경
.delete() ← 연락처 삭제 처리

서버 사이드 렌더링 방식으로도 바꿔볼 거임

자바 프로그램의 역할을 명확
서로 맞물려 있어서 명확하게 분리해서 공부할 수 없음

http://localhost:8080/contact/index.html

특수대학원
디지털대

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MyList!</title>
</head>
<body>
<h1>MyList에 오신 걸 환영합니다!</h1>
<p>이 프로젝트는 자바 실전 프로그래밍을 경험하기 위해 만든 프로젝트입니다.</p>
<ul>
  <li><a href="contact/index.html">연락처</a></li>
</ul>
</body>
</html>

다 기본으로 tboby로 들어감

tr = table row
th = table head
td = table data

<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
  <meta charset="utf-8">
  <title></title>
</head>
<body>
<h1>연락처</h1>
<table border="1">
  <tr>
    <th>이름</th>
    <th>이메일</th>
    <th>전화</th>
    <th>회사</th>
  </tr>
   <tr>
     <td>홍길동</td>
     <td>hong@test.com</td>
     <td>010-1111-1111</td>
     <td>비트캠프</td>
   </tr>
   <tr>
     <td>홍길동2</td>
     <td>hong@test.com</td>
     <td>010-1111-1111</td>
     <td>비트캠프</td>
   </tr>
</table>
</body>
</html>

tbody로 들어감

<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
  <meta charset="utf-8">
  <title></title>
</head>
<body>
<h1>연락처</h1>
<table border="1">
  <thead>
    <tr>
      <th>이름</th>
      <th>이메일</th>
      <th>전화</th>
      <th>회사</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>홍길동</td>
      <td>hong@test.com</td>
      <td>010-1111-1111</td>
      <td>비트캠프</td>
    </tr>
    <tr>
      <td>홍길동2</td>
      <td>hong@test.com</td>
      <td>010-1111-1111</td>
      <td>비트캠프</td>
    </tr>
  </tbody>
</table>
</body>
</html>

<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
  <meta charset="utf-8">
  <title></title>
</head>
<body>
<h1>연락처</h1>
<table border="1">
  <thead>
    <tr>
      <th>이름</th>
      <th>이메일</th>
      <th>전화</th>
      <th>회사</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>홍길동</td>
      <td>hong@test.com</td>
      <td>010-1111-1111</td>
      <td>비트캠프</td>
    </tr>
    <tr>
      <td>홍길동2</td>
      <td>hong@test.com</td>
      <td>010-1111-1111</td>
      <td>비트캠프</td>
    </tr>
  </tbody>
</table>
<script type="text/javascript">
  var contacts = [
    "aaa1,aaa@test.com,1111,비트캠프",
    "aaa2,aaa@test.com,1111,비트캠프",
    "aaa3,aaa@test.com,1111,비트캠프",
    "aaa4,aaa@test.com,1111,비트캠프",
    "aaa5,aaa@test.com,1111,비트캠프"
  ];

  for (contact item of contacts) {
    console.log(contact);
  }
</script>
</body>
</html>

문자열에서 이름, 이메일, 전화, 회사 정보 추출

<script type="text/javascript">
  var contacts = [
    "aaa1,aaa@test.com,1111,비트캠프",
    "aaa2,aaa@test.com,1111,비트캠프",
    "aaa3,aaa@test.com,1111,비트캠프",
    "aaa4,aaa@test.com,1111,비트캠프",
    "aaa5,aaa@test.com,1111,비트캠프"
  ];

  for (var contact of contacts) {
    console.log(contact.split(","));
  }
</script>

<script type="text/javascript">
  var contacts = [
    "aaa1,aaa@test.com,1111,비트캠프",
    "aaa2,aaa@test.com,1111,비트캠프",
    "aaa3,aaa@test.com,1111,비트캠프",
    "aaa4,aaa@test.com,1111,비트캠프",
    "aaa5,aaa@test.com,1111,비트캠프"
  ];

  for (var contact of contacts) {
    var values = contact.split(",");
    console.log(values[0], values[1], values[2], values[3]);
  }
</script>

테이블에 추가할 tr 태그 생성

이것은 <b>자바</b>입니다.

'자바' 데이터를 제어하는 데이터
다른 데이터를 제어하는 데이터 = meta data = markup = tag
tag는 다른 데이터를 제어하는 데이터
마크업이라고 부르기도 하고 태그라고 부르기도 한다
Hyper-Text Markup Language(HTML)

요소(element) = tag
<시작태그>콘텐트<끝태그>

<script type="text/javascript">
  var contacts = [
    "aaa1,aaa@test.com,1111,비트캠프",
    "aaa2,aaa@test.com,1111,비트캠프",
    "aaa3,aaa@test.com,1111,비트캠프",
    "aaa4,aaa@test.com,1111,비트캠프",
    "aaa5,aaa@test.com,1111,비트캠프"
  ];

  for (var contact of contacts) {
    var values = contact.split(",");
    var tr = document.createElement("tr");
    tr.innerHTML = `<td>${values[0]}</td>
    <td>${values[1]}</td>
    <td>${values[2]}</td>
    <td>${values[3]}</td>`
    console.log(tr);
  }
</script>

tr 태그를 테이블에 추가

table에 id 부여

x-contact-table

html은 대소문자 구문 안 함

<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
  <meta charset="utf-8">
  <title></title>
</head>
<body>
<h1>연락처</h1>
<table id="x-contact-table" border="1">
  <thead>
    <tr>
      <th>이름</th>
      <th>이메일</th>
      <th>전화</th>
      <th>회사</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>홍길동</td>
      <td>hong@test.com</td>
      <td>010-1111-1111</td>
      <td>비트캠프</td>
    </tr>
    <tr>
      <td>홍길동2</td>
      <td>hong@test.com</td>
      <td>010-1111-1111</td>
      <td>비트캠프</td>
    </tr>
  </tbody>
</table>
<script type="text/javascript">
  var contacts = [
    "aaa1,aaa@test.com,1111,비트캠프",
    "aaa2,aaa@test.com,1111,비트캠프",
    "aaa3,aaa@test.com,1111,비트캠프",
    "aaa4,aaa@test.com,1111,비트캠프",
    "aaa5,aaa@test.com,1111,비트캠프"
  ];

  var tbody = document.querySelector("#x-contact-table tbody")

  for (var contact of contacts) {
    var values = contact.split(",");
    var tr = document.createElement("tr");
    tr.innerHTML = `<td>${values[0]}</td>
    <td>${values[1]}</td>
    <td>${values[2]}</td>
    <td>${values[3]}</td>`

    tbody.appendChild(tr);

  }
</script>
</body>
</html>

기존에 홍길동 지우기

package com.eomcs.mylist;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController // 이 클래스가 클라이언트 요청 처리 담당자임을 표시한다.
public class ContactController {

  @RequestMapping("/contact/list")
  public Object list() {
    String[] contacts = {
        "aaa1,aaa@test.com,1111,비트캠프",
        "aaa2,aaa@test.com,1111,비트캠프",
        "aaa3,aaa@test.com,1111,비트캠프",
        "aaa4,aaa@test.com,1111,비트캠프",
        "aaa5,aaa@test.com,1111,비트캠프"
    };
    return contacts;
  };

}

["aaa1,aaa@test.com,1111,비트캠프","aaa2,aaa@test.com,1111,비트캠프","aaa3,aaa@test.com,1111,비트캠프","aaa4,aaa@test.com,1111,비트캠프","aaa5,aaa@test.com,1111,비트캠프"]

백엔드 개발자는 자기 할 일이 끝났어

프론트엔드 개발 시작

AJAX를 이용하여 서버의 REST API와 연동하기

fetch("/contact/list").then().then()

서버에서 응답이 오면 then
response => response.json()
파싱해서 자바스크립트 객체로 만든다
자바스크립트 객체로 만든 걸 리턴해달라고 한다

서버와 연결
서버에 요청
서버로부터 응답

fetch(url).then(함수)
서버로부터 응답을 받으면 함수가 호출되고
fetch(url).then(함수).then(함수)
이전 함수의 작업이 끝나면 호출

예외가 발생했을 때 호출될 함수를 등록하는 문법이 있겠지

대분류 소분류 상세 상세 검색

js fetch

https://developer.mozilla.org/ko/docs/Web/API/Fetch_API/Using_Fetch

.catch(error => console.error(error));

<script type="text/javascript">

  var tbody = document.querySelector("#x-contact-table tbody")

  fetch("/contact/list")
    .then(response => response.json())
    .then(contacts => {
      for (var contact of contacts) {
        var values = contact.split(",");
        var tr = document.createElement("tr");
        tr.innerHTML = `<td>${values[0]}</td>
        <td>${values[1]}</td>
        <td>${values[2]}</td>
        <td>${values[3]}</td>`

        tbody.appendChild(tr);

      }
    })

</script>

console.log(response);

console.log(response.json());

  @RequestMapping("/contact/add")
  public Object add(String name, String email, String tel, String company) {
    String contact = name + "," + email + "," + tel + "," + company;
    return contact;
  }

http://localhost:8080/contact/add?name=aaa&email=aaa@test.com&tel=010-1111-1111&company=%EB%B9%84%ED%8A%B8%EB%B9%84%ED%8A%B8

<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
  <meta charset="utf-8">
  <title>연락처</title>
</head>
<body>
<h1>새 연락처</h1>
<form>
  이름 : <input type="text"><br>
  이메일 : <input type="text"><br>
  전화 : <input type="text"><br>
  회사 : <input type="text"><br>
  <button type="button">등록</button>
</form>
</body>
</html>

<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
  <meta charset="utf-8">
  <title>연락처</title>
</head>
<body>
<h1>새 연락처</h1>
<form>
  이름 : <input type="text"><br>
  이메일 : <input type="text"><br>
  전화 : <input type="text"><br>
  회사 : <input type="text"><br>
  <button id="x-add-btn" type="button">등록</button>
</form>

<script type="text/javascript">
  var addBtn = document.querySelector("#x-add-btn");
  addBtn.onclick = function() {
    console.log("click!")
  };
</script>
</body>
</html>

버튼을 클릭할 때 입력 폼의 값 알아내기

<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
  <meta charset="utf-8">
  <title>연락처</title>
</head>
<body>
<h1>새 연락처</h1>
<form>
  이름 : <input id="x-name" type="text"><br>
  이메일 : <input id="x-email" type="text"><br>
  전화 : <input id="x-tel" type="text"><br>
  회사 : <input id="x-company" type="text"><br>
  <button id="x-add-btn" type="button">등록</button>
</form>

<script type="text/javascript">
  var addBtn = document.querySelector("#x-add-btn");
  addBtn.onclick = function() {
    var name = document.querySelector("#x-name");
    var email = document.querySelector("#x-email");
    var tel = document.querySelector("#x-tel");
    var company = document.querySelector("#x-company");

    console.log(name.value, email.value, tel.value, company.value);

  };
</script>
</body>
</html>

입력된 값 서버에 보내기

입력된 값을 서버에 보내서 등록

REST API 호출

서버에서 json으로 리턴 안 하고 문자열로 리턴했으니까
response.text()

<script type="text/javascript">
  var addBtn = document.querySelector("#x-add-btn");

  addBtn.onclick = function() {
    var name = document.querySelector("#x-name");
    var email = document.querySelector("#x-email");
    var tel = document.querySelector("#x-tel");
    var company = document.querySelector("#x-company");

    // console.log(name.value, email.value, tel.value, company.value);

    fetch(`/contact/add?name=${name.value}&email=${email.value}&tel=${tel.value}&company=${company.value}`)
      .then(function(response) {
        return response.text();
      })
      .then(function(text) {
        console.log(text);
      });

  };
</script>

json 문자열은 양쪽에 더블 쿼테이션 붙어야 됨

  @RequestMapping("/contact/add")
  public Object add(String name, String email, String tel, String company) {
    String contact = "\"" + name + "," + email + "," + tel + "," + company + "\"";
    return contact;
  }

<script type="text/javascript">
  var addBtn = document.querySelector("#x-add-btn");

  addBtn.onclick = function() {
    var name = document.querySelector("#x-name");
    var email = document.querySelector("#x-email");
    var tel = document.querySelector("#x-tel");
    var company = document.querySelector("#x-company");

    // console.log(name.value, email.value, tel.value, company.value);

    fetch(`/contact/add?name=${name.value}&email=${email.value}&tel=${tel.value}&company=${company.value}`)
      .then(function(response) {
        // return response.text();
        return response.json(); // json 형식의 문자열을 자바스크립트 객체로
      })
      .then(function(text) {
        console.log(text);
      });

  };
</script>

다시 수정해놓기

취소 버튼 추가

  <button id="x-add-btn" type="button">등록</button>
  <button id="x-cancel-btn" type="button">취소</button>
</form>

<script type="text/javascript">
  var addBtn = document.querySelector("#x-add-btn");
  var cancelBtn = document.querySelector("#x-cancel-btn");

이름 지을 때 일관성 지키기

  cancelBtn.onclick = function() {
    window.location.href = "index.html";
  };

취소 버튼 누르니까 목록으로 감

리팩토링(refactoring), 최적화(optimizing)

소스 코드를 관리하기 좋게 변경하는 것
대가 → 실행속도가 떨어질 수 있다.

실행 횟수를 줄이고 실행속도를 높이는 방향으로 소스코드를 변경하는 것
대가 → 소스코드가 난해해진다.

한 번만 사용하는 변수
리팩토링 - replace temp with query
한 번 밖에 안 쓰는 임시 변수인 경우는 메소드 호출할 때 직접 직어 넣어라
함수의 리턴 값을 받는 변수를 한 번만 사용할 경우 변수 대신 함수 호출을 삽입하라
즉 임시 변수를 사용할 자리에 함수 호출을 그대로 집어 넣어라!

addBtn, calcelBtn 없앰

<script type="text/javascript">

  document.querySelector("#x-add-btn").onclick = function() {

    var name = document.querySelector("#x-name");
    var email = document.querySelector("#x-email");
    var tel = document.querySelector("#x-tel");
    var company = document.querySelector("#x-company");

    // console.log(name.value, email.value, tel.value, company.value);

    fetch(`/contact/add?name=${name.value}&email=${email.value}&tel=${tel.value}&company=${company.value}`)
      .then(function(response) {
        return response.text();
        // return response.json(); // json 형식의 문자열을 자바스크립트 객체로
      })
      .then(function(text) {
        console.log(text);
      });

  };

  document.querySelector("#x-cancel-btn").onclick = function() {
    window.location.href = "index.html";
  };
</script>

필수 입력 항목 검사하기

별표(*) 항목은 필수 입력입니다.

<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
  <meta charset="utf-8">
  <title>연락처</title>
</head>
<body>
<h1>새 연락처</h1>
<form>
  이름* : <input id="x-name" type="text"><br>
  이메일* : <input id="x-email" type="text"><br>
  전화* : <input id="x-tel" type="text"><br>
  회사 : <input id="x-company" type="text"><br>
  별표(*) 항목은 필수 입력입니다.<br>
  <button id="x-add-btn" type="button">등록</button>
  <button id="x-cancel-btn" type="button">취소</button>
</form>

<script type="text/javascript">

  document.querySelector("#x-add-btn").onclick = function() {

    var name = document.querySelector("#x-name");
    var email = document.querySelector("#x-email");
    var tel = document.querySelector("#x-tel");
    var company = document.querySelector("#x-company");

    // console.log(name.value, email.value, tel.value, company.value);

    if (name.value == "" || email.value == "" || tel.value == "") {
      window.alert("필수 입력 항목이 비어 있습니다.");
      return;
    }

    fetch(`/contact/add?name=${name.value}&email=${email.value}&tel=${tel.value}&company=${company.value}`)
      .then(function(response) {
        return response.text();
        // return response.json(); // json 형식의 문자열을 자바스크립트 객체로
      })
      .then(function(text) {
        console.log(text);
      });

  };

  document.querySelector("#x-cancel-btn").onclick = function() {
    window.location.href = "index.html";
  };
</script>
</body>
</html>

자바스크립트는 브라우저가 실행

최적화 - 태그 찾기를 리스너 밖에 둔다.

밖으로 빼서 한 번만 찾게 한다.

이전에 찾은 걸 그대로 사용한다.

tag 객체의 기본 변수를 properties 라고 한다.
id, type, className, name

기본 변수 + 프로퍼티 추가

.onclick → .name

리스너에서 변수를 찾을 때 로컬 변수가 없는 경우 태그 객체에서 찾는다.
태그 객체에도 없다면, window 객체(글로벌 객체)에서 찾는다.

https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onkeydown

<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
  <meta charset="utf-8">
  <title>연락처</title>
</head>
<body>
<h1>새 연락처</h1>
<form>
  이름* : <input id="x-name" type="text"><br>
  이메일* : <input id="x-email" type="text"><br>
  전화* : <input id="x-tel" type="text"><br>
  회사 : <input id="x-company" type="text"><br>
  별표(*) 항목은 필수 입력입니다.<br>
  <button id="x-add-btn" type="button">등록</button>
  <button id="x-cancel-btn" type="button">취소</button>
</form>

<script type="text/javascript">
  var xName = document.querySelector("#x-name");
  var xEmail = document.querySelector("#x-email");
  var xTel = document.querySelector("#x-tel");
  var xCompany = document.querySelector("#x-company");

  document.querySelector("#x-add-btn").onclick = function() {


    // console.log(name.value, email.value, tel.value, company.value);

    if (xName.value == "" || xEmail.value == "" || xTel.value == "") {
      window.alert("필수 입력 항목이 비어 있습니다.");
      return;
    }

    fetch(`/contact/add?name=${xName.value}&email=${xEmail.value}&tel=${xTel.value}&company=${xCompany.value}`)
      .then(function(response) {
        return response.text();
        // return response.json(); // json 형식의 문자열을 자바스크립트 객체로
      })
      .then(function(text) {
        console.log(text);
      });

  };

  document.querySelector("#x-cancel-btn").onclick = function() {
    window.location.href = "index.html";
  };
</script>
</body>
</html>

등록 후 목록 화면으로 이동

    fetch(`/contact/add?name=${xName.value}&email=${xEmail.value}&tel=${xTel.value}&company=${xCompany.value}`)
      .then(function(response) {
        return response.text();
        // return response.json(); // json 형식의 문자열을 자바스크립트 객체로
      })
      .then(function(text) {
        console.log(text);
        location.href = "index.html";
      });

등록 버튼 누르면 목록 화면으로 이동함

REST API 기능 변경

연락처 데이터 유지
배열을 로컬 변수에서 인스턴스 변수로 전환한다.

몇 번째에 넣어야 되는지 모르잖아
size
배열에 집어 넣은 개수

package com.eomcs.mylist;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController 
// 이 클래스가 클라이언트 요청 처리 담당자임을 표시한다.
// 이 표시(애노테이션)가 붙어있어야만 스프링 부트가 인식한다.
public class ContactController {

  String[] contacts = new String[5];
  int size = 0;

  @RequestMapping("/contact/list")
  public Object list() {
    return contacts;
  };

  @RequestMapping("/contact/add")
  public Object add(String name, String email, String tel, String company) {
    String contact = name + "," + email + "," + tel + "," + company;
    contacts[size++] = contact;
    return size;
  }

}
  @RequestMapping("/contact/list")
  public Object list() {
    return contacts;
  };

지금 들어가 있는 개수만 리턴해야 됨

배열에 저장된 값만 새 배열을 만든다.

  @RequestMapping("/contact/list")
  public Object list() {
    String[] arr = new String[size]; // 배열에 저장된 값만 복사할 새 배열을 만든다.
    for (int i = 0; i < size; i++) {
      arr[i] = contacts[i]; // 전에 배열에서 값이 들어 있는 항목만 복사한다.
    }
    return arr; // 복사한 항목들을 담고 있는 새 배열을 리턴한다.
  };

http://localhost:8080/contact/add?name=aaa&email=aaa@test.com&tel=010-1111-1111&company=aaaa

쿼리 스트링으로 연락처 추가하고 목록 확인해보면 잘 나온다.

view.html

form.html을 복사해온다.

연락처의 이름에 상세보기 링크를 추가한다.

  var tbody = document.querySelector("#x-contact-table tbody")

  fetch("/contact/list").then(function(response){
  return response.json();
}).then(function(contacts) {
  console.log(contacts)
  for (var contact of contacts) {
    console.log(contact); // 예) "홍길동1,hong@test.com,010-1111-2222,비트캠프"
    var contact = contact.split(","); // 예) ["홍길동1","hong@test.com","010-1111-2222","비트캠프"]
    var tr = document.createElement("tr");
    tr.innerHTML = `<td><a href="/contact/get?email=${contact[1]}">${contact[0]}</a></td>
      <td>${contact[1]}</td>
      <td>${contact[2]}</td>
      <td>${contact[3]}</td>`;
    tbody.appendChild(tr);
  }
});

URL에서 쿼리스트링을 추출한다.
쿼리스트링에서 이메일 값을 추출한다.

0개 이상의 ~로 구성된 객체
빈 상자 있을 수 있잖아

한 번에 코딩해
그 다음 다시 0번에서 3번까지 한 번에 코딩

어떤 사람이 뒤에 물음표를 안 주고

  var arr = location.href.split("?");
  console.log(arr);
  if (arr.length == 1) {
    alert("요청 형식이 올바르지 않습니다.")
    return;
  }
  console.log("=======>")

예외를 던진다.

  var arr = location.href.split("?");
  console.log(arr);
  if (arr.length == 1) {
    alert("요청 형식이 올바르지 않습니다.")
    throw "URL 형식 오류!";
  }
  var arr = location.href.split("?");
  console.log(arr);
  if (arr.length == 1) {
    alert("요청 형식이 올바르지 않습니다.")
    throw "URL 형식 오류!";
  }

  var qs = arr[1];
  console.log(qs);

쿼리스트링에서 이메일 값을 추출한다
이걸 다시 &로 자르고

javascript string 검색

  // 2) 쿼리 스트링에서 email 값을 추출한다.
  var values = qs.split("&");
  for (var value of values) {
    if (value.startsWith("email=")) {
      console.log("ok!");
      break;
    }
  }

  // 2) 쿼리 스트링에서 email 값을 추출한다.
  var values = qs.split("&");
  for (var value of values) {
    if (value.startsWith("email=")) {
      console.log(value.split("=")[1]);
      break;
    }
  }

  // 2) 쿼리 스트링에서 email 값을 추출한다.
  var email = null;
  var values = qs.split("&");
  for (var value of values) {
    if (value.startsWith("email=")) {
      email = value.split("=")[1];
      break;
    }
  }

  if (email == null) {
    alert("이메일 값이 없습니다.");
    throw "파라미터 오류"
  }

파라미터 오류. 이메일 값이 안 넘어왔다

이메일을 가지고 서버에 상세 정보 요청하기

  // 3) 서버에서 가져온 데이터를 화면에 출력한다.
  var contact = "홍길동,hong@test.com,1111,비트캠프";
  var values = contact.split(",");
  // fetch(`/contact/get?email=${email}`)
  //   .then(funciton(response) {
  //     return
  //   })
  //   .then();

  var xName = document.querySelector("#x-name");
  var xEmail = document.querySelector("#x-email");
  var xTel = document.querySelector("#x-tel");
  var xCompany = document.querySelector("#x-company");

  xName.value = values[0];
  xEmail.value = values[1];
  xTel.value = values[2];
  xCompany.value = values[3];
  // 3) 연락처 상세 정보를 화면에 출력한다.
  var contact = "홍길동,hong@test.com,1111,비트캠프";
  var values = contact.split(",");

  var xName = document.querySelector("#x-name");
  var xEmail = document.querySelector("#x-email");
  var xTel = document.querySelector("#x-tel");
  var xCompany = document.querySelector("#x-company");

  xName.value = values[0];
  xEmail.value = values[1];
  xTel.value = values[2];
  xCompany.value = values[3];

REST API 구현 - get

배열에 입력된 개수만 반복해야 됨
size

반복문 다 돌 때까지 값을 못 찾은 경우에는 빈 문자열 리턴하기

  @RequestMapping("/contact/get")
  public Object get(String email) {
    for (int i = 0; i < size; i++) {
      if (contacts[i].split(",")[1].equals(email)) {
        return contacts[i];
      }
    }
    return "";
  }

서버 바꾸면 리스타트 됨
서버 리스타트 되는 순간 다시 연락처 등록해야 됨

학습용
실전
쓸데없이 임시변수 만들지 않는다

화면과 REST API 연동

서버에서 데이터 가져온다.

<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
  <meta charset="utf-8">
  <title>연락처</title>
</head>
<body>
<h1>연락처 상세</h1>
<form>
  이름* : <input id="x-name" type="text"><br>
  이메일* : <input id="x-email" type="text"><br>
  전화* : <input id="x-tel" type="text"><br>
  회사 : <input id="x-company" type="text"><br>
  별표(*) 항목은 필수 입력입니다.<br>
  <button id="x-update-btn" type="button">변경</button>
  <button id="x-cancel-btn" type="button">취소</button>
</form>

<script type="text/javascript">

  // URL에서 쿼리스트링(query string)을 추출한다.
  var arr = location.href.split("?");
  console.log(arr);
  if (arr.length == 1) {
    alert("요청 형식이 올바르지 않습니다.")
    throw "URL 형식 오류!";
  }

  var qs = arr[1];
  console.log(qs);

  // 2) 쿼리 스트링에서 email 값을 추출한다.
  var email = null;
  var values = qs.split("&");
  for (var value of values) {
    if (value.startsWith("email=")) {
      email = value.split("=")[1];
      break;
    }
  }

  if (email == null) {
    alert("이메일 값이 없습니다.");
    throw "파라미터 오류"
  }

  console.log(email);

  var xName = document.querySelector("#x-name");
  var xEmail = document.querySelector("#x-email");
  var xTel = document.querySelector("#x-tel");
  var xCompany = document.querySelector("#x-company");

  // 3) 서버에서 데이터 가져오기
  fetch(`/contact/get?email=${email}`)
    .then(function(response) {
      return response.text();
    })
    .then(function(contact) {
      var values = contact.split(",");

      // 4) 연락처 상세 정보를 화면에 출력한다.
      xName.value = values[0];
      xEmail.value = values[1];
      xTel.value = values[2];
      xCompany.value = values[3];
    })

  document.querySelector("#x-update-btn").onclick = function() {
    if (xName.value == "" || xEmail.value == "" || xTel.value == "") {
      window.alert("필수 입력 항목이 비어 있습니다.");
      return;
    }

    fetch(`/contact/add?name=${xName.value}&email=${xEmail.value}&tel=${xTel.value}&company=${xCompany.value}`)
      .then(function(response) {
        return response.text();
        // return response.json(); // json 형식의 문자열을 자바스크립트 객체로
      })
      .then(function(text) {
        console.log(text);
        location.href = "index.html";
      });

  };

  document.querySelector("#x-cancel-btn").onclick = function() {
    window.location.href = "index.html";
  };
</script>
</body>
</html>

쿼리스트링 분석기

https://developer.mozilla.org/ko/docs/Web/API/URLSearchParams

없으면 null 리턴

  // 2) 쿼리 스트링에서 email 값을 추출한다.
  var params = new URLSearchParams(qs)
  var email = params.get("email");

연락처 변경 구현

이메일을 데이터를 찾는 키로 사용하고 있음
연락처 정보를 입력할 때 연락처를 구분하는 별도의 값을 준비해야 됨
연락처를 등록할 때마다 고유번호(고유값)
키값은 보통 번호를 씁니다
전화번호, 이메일은 나중에 바뀔 수 있음
사용자 고유 번호
주민번호 같음
회원가입할 때 회원한테 고유번호 발급

이메일은 중복되면 안 된다. 수정도 불가능하다.

이메일* : <input id="x-email" type="text" readonly><br>

html은 2개의 속성이 있는데
이름과 값이 있는 것과
이름만 있는 거? 값은 의미가 없음. readonly 있는지 없는지만 봄.

안 바뀜

이메일 맨 위로 올리기

변경한 내용을 서버에 보낸다.

변경한 내용을 읽는다.

업데이트 안 만들어서 에러 남

  @RequestMapping("/contact/update")
  public Object update(String name, String email, String tel, String company) {
    String contact = name + "," + email + "," + tel + "," + company;
    for (int i = 0; i < size; i++) {
      if (contacts[i].split(",")[1].equals(email)) {
        contacts[i] = contact;
        return 1;
      }
    }
    return 0;
  }

http://localhost:8080/contact/update?name=a1&email=a1@test.com&tel=010-1111-1111&company=%EB%B9%84%ED%8A%B8%EC%BA%A0%ED%94%8412

연락처 삭제 구현

화면 구현

삭제 버튼 추가 및 리스너를 등록한다.

<form>
  이메일* : <input id="x-email" type="text" readonly><br>
  이름* : <input id="x-name" type="text"><br>
  전화* : <input id="x-tel" type="text"><br>
  회사 : <input id="x-company" type="text"><br>
  별표(*) 항목은 필수 입력입니다.<br>
  <button id="x-update-btn" type="button">변경</button>
  <button id="x-delete-btn" type="button">삭제</button>
  <button id="x-cancel-btn" type="button">취소</button>
</form>

<button id="x-delete-btn" type="button">삭제</button>

document.querySelector("#x-delete-btn").onclick = function() {
  console.log("삭제!");
};

서버에 삭제를 요청한다.

이 변수 쓰는 거임

response.json();

숫자는 더블 쿼테이션 안 붙음

  document.querySelector("#x-delete-btn").onclick = function() {
    fetch(`/contact/delete?email=${email}`)
      .then(function(response) {
        return response.json();
      })
      .then(function(result) {
        console.log(result);
      })
  };

배열 삭제

잘라서 앞에 붙이는 거

  @RequestMapping("/contact/delete")
  public Object delete(String email) {
    for (int i = 0; i < size; i++) {
      if (contacts[i].split(",")[1].equals(email)) {
        // 현재 위치의 다음 항목에서 배열끝까지 반복하여 앞으로 값을 당겨온다.

        for (int j = i + 1; j < size; j++) {
          contacts[j-1] = contacts[j];
        }
        size--;
        return 1; 
      }
    }
    return 0;
  }

지운 거 또 지우라고 하면 0 나옴

서버와 연동

문자열은 양끝에 더블 쿼테이션을 붙여야 한다.

숫자는 그대로 JSON 형식이다.

  document.querySelector("#x-delete-btn").onclick = function() {
    fetch(`/contact/delete?email=${email}`)
      .then(function(response) {
        return response.json();
      })
      .then(function(result) {
        console.log(result);
        location.href = "index.html"
      })
  };

CRUD 하기....

My1Controller.java

필수항목은 뭐뭐입니다.
어떤 항목을 키로 사용하기로 했습니다.

0개의 댓글