Project Memo Part 1 (1. 기본)

박영준·2022년 11월 28일
0

Java

목록 보기
10/111

1. 필요한 기능

  1. 접속 하자마자 메모 전체 목록 조회하기
    1) GET API 사용해서 메모 목록 불러오기
    2) 메모 마다 HTML 만들고 붙이기

  2. 메모 생성하기
    1) 사용자가 입력한 메모 내용 확인하기
    2) POST API 사용해서 신규 메모 생성하기
    3) 화면 새로고침하여 업데이트 된 메모 목록 확인하기

  3. 메모 변경하기
    1) 사용자가 선택하고 수정한 메모가 어떤 것인지 확인
    2) 변경한 메모 내용 확인
    3) PUT API 사용해서 메모 내용 변경하기
    4) 화면 새로고침하여 업데이트 된 메모 목록 확인하기

  4. 메모 삭제하기
    1) 사용자가 선택한 메모가 어떤 것인지 확인
    2) DELETE API 사용해서 메모 삭제하기
    3) 화면 새로고침하여 업데이트 된 메모 목록 확인하기


2. 스프링 MVC - Response, Request

스프링 MVC 동작원리
참고: @Controller, @RestController - Controller로 View 반환


Star.java

package com.sparta.springmvc;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@AllArgsConstructor
public class Star {
    String name;
    int age;
}

HelloRestController.java

//스프링 MVC - Response
//@RestController = @Controller + @ResponseBody
    //@RestController은 @ResponseBody를 사용하지 않아도 반환 가능
package com.sparta.springmvc;

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

import java.util.Arrays;
import java.util.List;

@RestController
@RequestMapping("/rest")
public class HelloRestController {

    @GetMapping("/json/string")
    public String helloHtmlString() {
        return "<html><body>Hello @ResponseBody</body></html>";
    }

    @GetMapping("/json/list")
    public List<String> helloJson() {
        List<String> words = Arrays.asList("Hello", "Controller", "And", "JSON");

        return words;
    }
}

HelloResponseController.java

//스프링 MVC - Response
//@Controller 가 달려있는 Controller
    //@Controller은 return 반환 하려고 할 때, @ResponseBody를 추가했어야만 했음 (@RestController 과 차이점)
package com.sparta.springmvc;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

@Controller     //@Controller를 사용하면, 바디를 자바객체로 받기 위해서는 @ResponseBody 어노테이션을 반드시 명시해주어야함
@RequestMapping("/response")        //RequestMapping을 사용해서, 전체 URL을 response로 시작하도록 설정
public class HelloResponseController {

    private static long visitCount = 0;     //static을 사용해서, 방문자수를 증가시켜주는 변수 visitCount을 선언

    @GetMapping("/html/redirect")       //html/redirect으로 요청이 들어왔을 때, static Directory에 있는 hello.html을 반환
    public String htmlFile() {          // 반환값이 String인 메서드 htmlFile()
        return "redirect:/hello.html";      //주의! 단순한 String이 아니라, redirect와 html 이라는 표현이 추가돼있음!
    }

    @GetMapping("/html/templates")
    public String htmlTemplates() {
        return "hello";         //위와는 다르게, 그냥 hello 라는 String으로 반환
    }

    @ResponseBody       //자바객체를 HTTP요청의 바디내용으로 매핑하여 클라이언트로 전송(= http요청 body를 자바 객체로 전달받을 수 있다.)
    @GetMapping("/body/html")       //body/html  URL로 요청을 받으면,    --> localhost:8080/response/body/html 로 들어가서 콘솔창을 보면, 아래의 HTML 태그 형식으로 보이는 값들을 볼 수 있음
    public String helloStringHTML() {
        return "<!DOCTYPE html>" +      //HTML 태그 형식으로 보이는 값이 합쳐진 형태로 반환
                "<html>" +
                "<head><meta charset=\"UTF-8\"><title>By @ResponseBody</title></head>" +
                "<body> Hello, 정적 웹 페이지!!</body>" +
                "</html>";
    }
    
	// 예시
      // 1. response/html/dynamic이라는 요청이 GET방식으로 들어왔을 때, HelloResponseController 의 helloHtmlFile() 함수와 response/html/dynamic 가 매칭됨
      // 2. HelloResponseController에서 @GetMapping("/html/dynamic")과 연결돼서 아래의 메소드를 실행하게 됨
    @GetMapping("/html/dynamic")     //localhost:8080/response/html/dynamic 로 들어가면, 리턴값은 hello-visit이 나옴 --> hello-visit.html에서 (방문자 수: <span th:text="${visits}"></span>)에 따라 방문자 수는 1씩 계속 증가
    public String helloHtmlFile(Model model) {      //객체 model을 받았고     --> 위의 URL /html/dynamic 만 잘 매칭해주면, 메소드 이름 helloHtmlFile 것들은 개발자 마음대로 이름을 바꿔도 됨
        visitCount++;       //위의 private static long visitCount = 0; 에서 visitCount를 하나 추가한 후,
        model.addAttribute("visits", visitCount);       //객체 model 안에 key:value 형식으로 데이터를 넣고(visitCount를 하나 추가한 게 적용됨), 값을 반환
        return "hello-visit";       //반환
    }

    @ResponseBody
    @GetMapping("/json/string")     //localhost:8080/response/json/string 으로 들어가면, {"name":"르세라핌","age":20} 형식의 값이 보임
    public String helloStringJson() {
        return "{\"name\":\"르세라핌\",\"age\":20}";        //String 이지만, JSON 형식으로 된 값이 반환
    }

    @ResponseBody
    @GetMapping("/json/class")      //json/class URL로 요청받으면,  --> /localhost:8080/response/json/class 으로 들어가면, Star 객체가 반환
    public Star helloJson() {       //객체 Star가 반환
        return new Star("르세라핌", 20);        //초기값 "르세라핌", 20 은 생성자를 통해서 값을 주는 형태로 만들어짐
    }
}

HelloRequestController.java

//스프링 MVC - Request
package com.sparta.springmvc;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

@Controller
@RequestMapping("/request")
public class HelloRequestController {

    @GetMapping("/form/html")
    public String helloForm() {
        return "hello-request-form";
    }

    //@PathVariable
        //{ }중괄호가 PathVariable 형식으로 받는 부분 --> 안으로 들어온 값들을 받아주는 역할
    //이름: Ben, 나이: 20 --> Hello, @PathVariable.<br> name = %s, age = %d", name, age 형태로 값이 반환
    //--> 콘솔창 - 네트워크 탭에 보면 요청 URL에 localhost:8080/request/star/Ben/age/20 --> 내가 넣었던 값들이 URL안에 들어가 있음
    @GetMapping("/star/{name}/age/{age}")
    @ResponseBody
    public String helloRequestPath(@PathVariable String name, @PathVariable int age)
    {
        return String.format("Hello, @PathVariable.<br> name = %s, age = %d", name, age);
    }

    //@RequestParam: 값을 받는다
    
    //@RequestParam + GET 방식: 값이 겉으로 표현됨
    //이름: Ben, 나이: 20 --> 웹페이지 URL: localhost:8080/request/param?name=Ben&age=20
    //--> @RequestParam의 변수 name, 변수 age 와 쿼리 방식으로 날아오는 name, age (name=Ben&age=20 이 부분)와 매칭해서 값을 가져오는 방식
    @GetMapping("/form/param")
    @ResponseBody
    public String helloGetRequestParam(@RequestParam String name, @RequestParam int age) {
        return String.format("Hello, @RequestParam.<br> name = %s, age = %d", name, age);
    }

    //@RequestParam + POST 방식: 값이 표현되지 않고, 안으로 숨겨짐
    //이름: Ben, 나이: 20 --> 웹페이지 URL: localhost:8080/request/param --> URL에는 값의 변화가 적용되지 않음(POST 방식이므로)
    //--> 대신, 콘솔창 - 네트워크 탭 - 페이로드 에서 name, age 값이 들어간 것들 확인 할 수 있음
    @PostMapping("/form/param")
    @ResponseBody
    public String helloPostRequestParam(@RequestParam String name, @RequestParam int age) {
        return String.format("Hello, @RequestParam.<br> name = %s, age = %d", name, age);
    }


    //@ModelAttribute: 받아야 할 값이 많을 경우, 객체 형식으로 받는다(@RequestParam은 값이 적을 경우에 맞는 방법)
    //@ModelAttribute는 생략 가능
    //주의! @ModelAttribute를 사용할 때는 @Setter을 달아줘야지만 사용할 수 있음
    @PostMapping("/form/model")
    @ResponseBody
    public String helloRequestBodyForm(@ModelAttribute Star star) {
        return String.format("Hello, @RequestBody.<br> (name = %s, age = %d) ", star.name, star.age);
    }

    //@RequestBody : JSON 형식으로 값이 넘어감
    //@RequestBody과 그 값들을 받아오는 객체를 명시
    //주의! java에서 가지는 필드값과 Client 쪽에서 보내는 필드값이 일치해야 값을 받아올 수 있음
    @PostMapping("/form/json")
    @ResponseBody
    public String helloPostRequestJson(@RequestBody Star star) {
        return String.format("Hello, @RequestBody.<br> (name = %s, age = %d) ", star.name, star.age);
    }
}

hello.html

//HelloResponseControoler에서 @GetMapping("/html/redirect")과 연결됨
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>Hello Spring</title>
</head>
<body>
<div>
    Hello, Spring 정적 웹 페이지!!
</div>
</body>
</html>

hello-visit.html

<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="UTF-8">
  <title>Hello Spring</title></head>
<body>
<div>
  Hello, Spring 동적 웹 페이지!!
</div>
<div>
  (방문자 수: <span th:text="${visits}"></span>)
</div>
</body>
</html>

hello-request-form.html

//HelloRequestController를 테스트하기 위한 html
<!DOCTYPE html>
<html lang="ko">
<head>
  <title>Hello Request</title>
</head>
<body>
<h2>GET /request/star/{name}/age/{age}</h2>
<form id="helloPathForm">
  <div>
    이름: <input name="name" type="text">
  </div>
  <div>
    나이: <input name="age" type="text">
  </div>
</form>
<div>
  <button id="helloPathFormSend">전송</button>
</div>
<br>

<h2>GET /request/form/param</h2>
<form method="GET" action="/request/form/param">
  <div>
    이름: <input name="name" type="text">
  </div>
  <div>
    나이: <input name="age" type="text">
  </div>
  <button>전송</button>
</form>

<br>
<h2>POST /request/form/param</h2>
<form method="POST" action="/request/form/param">
  <div>
    이름: <input name="name" type="text">
  </div>
  <div>
    나이: <input name="age" type="text">
  </div>
  <button>전송</button>
</form>
<br>

<h2>POST /request/form/model</h2>
<form method="POST" action="/request/form/model">
  <div>
    이름: <input name="name" type="text">
  </div>
  <div>
    나이: <input name="age" type="text">
  </div>
  <button>전송</button>
</form>
<br>

<h2>POST /request/form/json</h2>
<form id="helloJsonForm">
  <div>
    이름: <input name="name" type="text">
  </div>
  <div>
    나이: <input name="age" type="text">
  </div>
</form>
<div>
  <button id="helloJsonSend">전송</button>
</div>
<div>
  <div id="helloJsonResult"></div>
</div>
</body>
<script>
  // GET /star/{name}/age/{age}
  const helloPathForm = document.querySelector("#helloPathFormSend")
  helloPathForm.onclick = (e) => {
    const form = document.querySelector("#helloPathForm");
    const name = form.querySelector('input[name="name"]').value;
    const age = form.querySelector('input[name="age"]').value;
    const relativeUrl = `/request/star/${name}/age/${age}`;
    window.location.href = relativeUrl;
  }

  // POST /hello/request/form/json
  const helloJson = document.querySelector("#helloJsonSend")
  helloJson.onclick = async (e) => {
    const form = document.querySelector("#helloJsonForm");

    const data = {
      name: form.querySelector('input[name="name"]').value,
      age: form.querySelector('input[name="age"]').value
    }

    const response = await fetch('/request/form/json', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(data),
    })

    const text = await response.text(); // read response body as text
    document.querySelector("#helloJsonResult").innerHTML = text;
  };
</script>
</html>
profile
개발자로 거듭나기!

0개의 댓글