[새싹 x 코딩온] 웹 풀스택 영등포 5기 20주차 회고 - 2

용가리🐉·2023년 12월 14일
0
post-thumbnail

📌 Spring Boot 프로젝트 생성하기

Spring Boot 프로젝트 시작하기

  • Spring Boot 기반으로 Spring 관련 프로젝트를 만들어주는 사이트
  • Spring에서 운영 중, 원하는 라이브러리를 선택 후 프로젝트 생성 가능
  • Project - 생성할 프로젝트의 빌드 자동화 툴
  • Language - 생성할 프로젝트의 언어
  • Spring Boot - 스프링 부트 버전
  • Project Metadata - 프로젝트 정보
  • Dependencies - 프로젝트 의존성 (여기에 추가한 디펜던시가 build.gradle 파일에 추가됨)
    • Spring Web: 스프링 기반으로 웹 기반
    • Thlymeleaf: 템플릿 엔진
    • Lombok: 코드 다이어트 라이브러리 (getter, setter 등 코드를 간단히 사용하게 함)

→ 스프링 부트는 8080 포트 번호를 사용해 내장 웹 서버를 실행함!

서버 포트번호 변경하기

  • application.properties 파일에서 별도 설정 필요
server.port = 7070

📣 프로젝트 구조 살펴보기

  • main/ : 실제 코드를 작성하는 곳
  • test/ : 프로젝트의 소스 코드를 테스트하는 코드 or 리소스 파일
  • build.gradle : 빌드 설정 파일 → GitHub에서 파일을 다운받아 실행해볼 때, 해당 파일을을 열어야 함
  • setting.gradle : 빌드할 프로젝트 정보 설정 파일

📌 Spring MVC

  • Spring에서 제공하는 웹 모듈로 웹 애플리케이션을 빌드하기 위한 프레임워크
  • Model, View, Controller의 3가지 구성 요소
    • Model: 데이터와 비즈니스 로직 처리
    • View: 사용자에게 보여지는 부분
    • Controller: 사용자의 요청을 받아 처리하고 적절한 Model을 호출한 후, 그 결과를 View에게 전달
  • MVC 패턴을 지원하고 DispatcherServlet이라는 특수 서블릿을 통해 요청 처리
    • 해당 서블릿은 모든 종류의 요청을 받아 적절한 Controller에게 전달하고, 그 결과를 다시 사용자에게 반환

정적 파일

  • ./src/main/resources/static은 정적 파일 위치

📌 Thymeleaf 템플릿


템플릿 엔진 (ex. JSP, Thymeleaf, FreeMarker, ...)

  • HTML 태그에 속성을 추가해 페지에 동적으로 값을 추가하거나 처리할 수 있게 도와주는 것
  • Spring Boot 사용 시 권장되는 템플릿 엔진

📣 Controller 만들기

package sesac.sesacspringboot.controller;

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

@Controller
public class HelloController {
	@GetMapping("/hi")
    public String getHi(Model model) {
    	model.addAttribute("msg", "Hi~");
        return "hi";
    }
}
  • @Controller
    • 해당 클래스가 Controller 클래스라는 것을 Spring Container에게 알려줌
  • @GetMapping
    • URL을 매핑시켜주는 것으로 get method로 해당 경로로 들어올 시, getHi라는 함수를 실행시킴

📣 Template view 만들기

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
	<p th:text="'안녕하세요. ' + ${msg}">안녕 반가워</p>
</body>
</html>

📣 Spring Boot 동작 환경

  • Spring boot는 WAS로 Tomcat을 내장
  1. localhost:8080/hello 요청 시, Tomcat이 Spring에게 넘겨줌
  2. 컨트롤러(HelloController.java)에서 매칭되는 URL을 찾음
  3. 해당 메소드(getHi)에서 반환하는 문자열을 ViewResolver가 화면을 찾아서 처리 (templates/hello.html)

WAS란?
Spring Boot 설명 회고록

  • Spring Boot의 주요 특징 중 하나
  • WAS (Web Application Server): 웹 애플리케이션 실행 장치

📌 Thymeleaf 표현식과 문법

📣 Thymeleaf 표현식

  • 서버에서 전달받은 데이터를 사용자들이 볼 수 있는 뷰로 만들기 위해 사용되는 표현식
  • ${...} : 변수의 값 표현식
  • #{...} : 속성 파일 값 표현식
  • @{...} : URL 표현식
  • *{...} : 선택한 변수의 표현식, th:object에서 선택한 객체에 접근
<p th:text="'안녕하세요. ' + ${hello}">안녕 반가워</p>
<p th:utext="${uText}"></p>
<input type="text" th:value="${value}">
<p th:with="temp=${withValue}" th:text="${temp}"></p>
<a th:href="@{/{id}(id=${link})}">Link1 (hi)</a><br>
<a th:href="@{/hi}">Link2 (hi)</a><br>
<a th:href="@{http://www.google.com}">Google</a><br>
<img th:src="${imgSrc}">

📣 Thymeleaf 문법

  • HTML 태그 안에 소 문법을 추가
  • div 태그 뿐만 아니라 HTML에서 지원하는 태그들 모두 사용 가능
<div th:[속성]="서버에서 받는 값 및 조건식" />

🟠 th:text

  • 태그 안의 텍스트를 서버에서 전달받은 값에 따라 표현하고자 할 때 사용하는 문법
<span th:text="${hello}">message</span>

🟠 th:utext

  • th:text와 유사
  • 변수에서 받은 값에 html 태그가 있다면 태그 값을 반영해서 표시해줌
  • "<strong>안녕</strong>" 값이 서버에서 넘어왔다면 <strong>이라는 글자가 나오는 것이 아닌 "안녕"이라는 글자가 <strong> 태그에 의해 굵게 표시됨

🟠 th:value

  • HTML Element의 value 속성 값을 지정할 때 사용
<button th:value="${hello}" />

🟠 th:with

  • 변수 값을 지정해서 사용하고자 할 때 사용
<div th:with="temp=${hello}" th:text="${temp}" />
  • 위와 같이 사용한다면, 서버에서 전달받은 'hello' 값이 저장된 temp라는 변수가 만들어지고, Thymeleaf 문법 내에서 사용 가능

🟠 th:switch

  • switch-case문을 이용할 때 사용되는 문법
  • th:case 에서 case 문을 다루고, *로 case문에서 다루지 않은 모든 경우가 처리됨 (*는 일반 switch-case 문에서의 default)
<div th:switch="${userRole}">
	<p th:case="'admin'">Hello, Admin</p>
    <p th:case="'user'">Hello, User</p>
    <p th:case="*">Hello, Unknown</p>
</div>

🟠 th:if

  • 조건문이 필요할 때 사용되는 문법
  • Else 문이 필요한 경우에는 th:unless를 사용
<div>
	<p th:if="${hello}=='web'" th:text="${hello}"></p>
    <p th:unless="${hello}=='web'" th:text="unless입니다."></p>
</div>
  • 주의: th:unless에 if에 적은 조건을 적어줘야 위의 if가 아닌 경우 인식 가능!

🟠 th:each

  • 반복문이 필요한 경우에 사용되는 문법
  • 리스트와 같은 collection 자료형을 서버에서 넘겨주면 그에 맞춰 반복적인 작업이 이뤄질 때 사용 가능
String[] names = {"kim", "lee", "hong", "park", "shin"};
model.Attribute("names", names);

return "05_Thymeleaf";
<ul>
	<li th:each="name:${names}" th:text="${name}"></li>
</ul>

📌 Rest API

  • REST의 규칙을 모두 지켜 구현된 웹 서비스를 RESTful 하다고 말함

RESTful 이란?

  • REST의 원리를 따르는 시스템
  • 원리를 따르기만 하면 다 RESTful이 아님
  • 원리를 따르면서 REST API 설계 규칙을 올바르게 지킨 시스템이 RESTful한 시스템

API, Rest에 대해 적은 회고록

  • 개발에서의 API는 요청과 응답을 구성하는 방법에 대한 정보가 들어있음

📣 Rest의 특징

  • Server-Client 구조
  • Stateless (무상태)
  • Cacheable (캐시 처리 가능)
  • Layered System (계층화)
  • Uniform Interface (인터페이스 일관성)

📣 Rest의 장단점

  • 장점
    • http 프로토콜의 인프라를 그대로 사용하므로 REST API 사용을 위한 별도의 인프라를 구축할 필요가 없음
    • http 표준 프로토콜을 따르는 모든 플랫폼에서 사용 가능
    • 서버와 클라이언트의 역할을 명확하게 분리함
  • 단점
    • http method 형태가 제한적
    • 구현 브라우저에서는 호환이 되지 않아 지원해주지 못하는 동작이 많음 (IE)

📌 DTO

Data Transfer Object

  • 계층 간 데이터 교환을 위해 사용하는 객체
    • 즉, 데이터를 옮기기 위해 사용하는 전달자 역할
  • 다른 로직을 가지지 않는 순수한 데이터 객체 (Java Beans)
import lombok.Getter;
import lombok.Setter;

// 별도의 Getter, Setter 구현 없이 사용하게 해주는 어노테이션
@Getter
@Setter 
public class DTOExample {
	private String title;
    private String content;
    private String writer;
}

📌 VO

Value Object

  • DTO와 비슷하지만, VO는 read-Only 속성을 갖고 있는 객체
  • Getter만 가지고 있어 값에 대한 수정 불가

DTO vs VO

📌 API (Get, Post)

📣 Get 방식

  • Get method의 URL을 받을 때 → Controller에서 @GetMapping(url)을 이용
@GetMapping(url 주소)
public String 함수이름() {
	return 템플릿 파일 명;
}

📣 (get) ?key=value

  • ?key=value 형태로 url이 넘어올 때 Controller에서 받는 방법 → @RequestParam
@GetMapping(url 주소)
public String 함수 이름(@RequestParam(value="key") String key) {
	return 템플릿 파일 명;
}
  • key라는 변수에 ?key=value 로 넘어온 value 값이 들어감
  • @RequestParam에 required 값을 설정하면 없어도 실행됨

📣 (get) ~/{value}

  • ~/{value} 형태로 url이 넘어올 때 Controller에서 받는 방법 → @PathVariable
@GetMapping(url 주소/{value})
public String 함수 이름(@PathVariable String value) {
	return 템플릿 파일 명;
}
  • value라는 변수에 url로 넘어온 값이 담김

🟠 만일 이름을 다르게 설정하고 싶을 경우

@GetMapping(url 주소/{value}/{value2})
public String 함수 이름(@PathVariable String value, @PathVariable("value2") String abc) {
	return 템플릿 파일 명;
}

🟠 required 설정하기

  • @Pathvariable에 required 설정이 가능하나, 기본값은 true
  • @Pathvariable에 required를 설정할 때는 GetMapping에 url도 같이 설정해줘야 한다.
  • required 값이 false 인 친구는 뒤로 가야한다.
@GetMapping("/get/response4/{name}/{age}")
public String getResponse4(@PathVariable(value="name") String n,
						   @PathVariable(required = false) String age,
                           Model model) {
	model.addAttribute("name", n);
	model.addAttribute("age", age);
	return "response";
}

📣 Post 방식

  • Post method의 URL을 받을 때 → Controller에서 @PostMapping(url)
  • Post로 값을 전달할 때 그 값을 controller에서 받는 방법 → @RequestParam
  • @RequestParam 역시 required 사용 가능
@PostMapping("/post/response1")
public String postResponse1(@RequestParam(value="name") String name, Model model) {
	model.addAttribute("name", name);
	return "response";
}

📣 API 이용하기

  • 앞에서는 return을 이용해 Template view를 무조건 불러옴
  • API로만, 데이터만 전달하고 싶을 경우 → @ResponseBody 이용
    • Node.js에서의 res.send()와 동일하다고 생각해도 무방!
@GetMapping("response-string")
@ResponseBody
public String getString(@RequestParam("name") String name) { return "hello " + name; }

@PostMapping("/post/response3")
@ResponseBody
// return 하는 문자열의 template 파일을 불러오는 게 아니라
// return 하는 문자열 그대로 값을 전달하는 것
public String postResponse3(@RequestParam(value="name", required = false) String name, Model model) {
	model.addAttribute("name", name);
	return "response";
}

📌 DTO 이용하기

  • UserDTO.java
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class UserDTO {
    private String name;

    private String age;
}
  • Controller
@GetMapping("/dto/response1")
@ResponseBody
public String dtoResponse1(@ModelAttribute UserDTO userDTO) {
	// 변수로 값을 하나씩 가져오는 게 아니라 객체에 값을 담아서 가져오고 싶을 때 사용하는 방법
    // @ModelAttribute : html 폼 데이터를 컨트롤러에 전달할 때 객체에 매핑해주는 친구 (매핑  = setter 함수를 실행한다)
    String msg = "이름 : " + userDTO.getName() + ", 나이 : " + userDTO.getAge();
    return msg;
}

@PostMapping("/dto/response2")
@ResponseBody
public String dtoResponse2(UserDTO userDTO) {
    // 아무것도 없는 상태 = @ModelAttribute 상태
    String msg = "이름 : " + userDTO.getName() + ", 나이 : " + userDTO.getAge();
    return msg;
}

@PostMapping("/dto/response3")
@ResponseBody
public String dtoResponse3(@RequestBody UserDTO userDTO) {
    // @RequestBody : 요청의 본문에 있는 데이터(body)를 받아와서 객체에 매핑( 필드값에 값을 주입 )
    // 전달받은 요청의 형식이 json 또는 xml 일 때만 실행이 가능
    // 일반 폼 전송 =  www-x-form-urlencoded -> 즉, Requestbody는 일반폼 전송의 형태를 처리할 수 없음
    String msg = "이름 : " + userDTO.getName() + ", 나이 : " + userDTO.getAge();
    return msg;
}

📌 VO 이용하기

  • UserVO.java
import lombok.Getter;

@Getter
public class UserVO {
    public String name, age;
}
  • Controller
// Q. get 방식 - vo = null ( modelAttribute = setter 함수를 실행)
// post 방식 - vo = null
// post 방식 - vo - requestbody = 오류
@GetMapping("/vo/response1")
@ResponseBody
public String voResponse1(UserVO userVo) {
	String msg = "이름 : " + userVo.getName() + ", 나이 : " + userVo.getAge();
    return msg;
}

@PostMapping("/vo/response2")
@ResponseBody
public String voResponse2(UserVO userVo) {
    String msg = "이름 : " + userVo.getName() + ", 나이 : " + userVo.getAge();
    return msg;
}

@PostMapping("/vo/response3")
@ResponseBody
public String voResponse3(@RequestBody UserVO userVo) {
    String msg = "이름 : " + userVo.getName() + ", 나이 : " + userVo.getAge();
    return msg;
}

📌 Axios 이용하기

front 코드 (GitHub)
back 코드 (GitHub)


📌 총정리

📣 일반 폼 전송

일반 폼 전송 시

  • RequestParam : Get과 Post 둘 다 가능
  • PathVariable : Get 만 가능

DTO

  • Get 전송 가능
  • Post 전송 - RequestBody가 없을 경우 가능
  • Post 전송 - RequestBody가 있을 경우 실패

VO

  • Get 전송 Null
  • Post 전송 - RequestBody가 없을 경우 Null
  • Post 전송 - RequestBody가 있을 경우 실패
  • RequestBody는 전달받은 요청의 형식이 json 또는 xml 일 때만 실행이 가능
  • 일반 폼 전송 = www-x-form-urlencoded → 즉, Requestbody는 일반폼 전송의 형태를 처리할 수 없음

📣 Axios 이용

DTO

  • Get 일반 : 가능
  • Get DTO : 가능
  • Post 일반 : 실패
  • Post DTO - RequestBody X : Null
  • Post DTO - RequestBody O : 가능

VO

  • Get 일반 : 가능
  • Get VO : Null
  • Post 일반 : 실패
  • Post VO - RequestBody X : Null
  • Post VO - RequestBody O : 가능
profile
자아를 찾아 떠나는 중,,,

0개의 댓글

관련 채용 정보