[SPRING] 인프런 스프링 입문 강의 공부기록. ~ 11강

2022. 2. 24. 22:16JAVA

1강 : 강의 목표 

' 스프링 학습의 제대로 된 첫 길잡이 '

기술 겉핥기!

 

방법

처음부터 끝까지 직접 코딩

 


 

2강 : 프로젝트 생성

필수 : Java 11, IntelliJ 

 

프로젝트 생성은  https://start.spring.io 에서

요즘은 대부분 gradle 쓴다.

spring boot 버전은 snapshot 아닌것중 최신

dependency = {spring web, Thymeleaf}

open 하면 라이브러리를 자동으로 다운받음 (gradle이 버전설정하고 라이브러리 땡겨오는구나 정도 이해)

main 메서드 run 후 localhost:8080 접속해서 error 페이지 뜨면 성공

 


 

3강 : 라이브러리 살펴보기

스프링 라이브러리끼리 의존관계가 있어서 필요한거 다 땡겨옴. 그래서 external libraries 에 목록 엄청 많음

옛날엔 WAS라고 서버를 설치해야 했는데 이젠 톰캣 내장

현업에선 system.out.prinltn() 안됨. log로 관리함

 

 


 

4강 : View 환경설정

error 페이지 말고 뭔가 하나 띄워보자

welcome page -> index.html

<!DOCTYPE HTML>
<html>
<head>
 <title>Hello</title>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
Hello
<a href="/hello">hello</a>
</body>
</html>

 

스프링은 워낙 방대해서 찾는 능력을 길러야 한다.

 

spring.io -> Projects -> Spring Boot -> Learn -> 버전에 맞는 Reference Doc. -> 에서 찾기

thymeleaf 공식 사이트: https://www.thymeleaf.org/

스프링 공식 튜토리얼: https://spring.io/guides/gs/serving-web-content/

스프링부트 메뉴얼: https://docs.spring.io/spring-boot/docs/2.3.1.RELEASE/reference/html/spring-boot-features.html#boot-features-spring-mvc-template-engines

 

 

controller 패키지 생성 - HelloController 클래스 생성

package hello.hellospring.controller;

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

@Controller
public class HelloController {
    @GetMapping("hello")
    public String hello(Model model){
        model.addAttribute("data","hello!!");
        return "hello";
    }
}

@GetMapping("hello") 의 의미 : 웹 어플리케이션에서 /hello 요청이 들어오면 해당 메서드를 호출해줌

 

 

 

templates - hello.html 생성

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
 <title>Hello</title>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p th:text="'안녕하세요. ' + ${data}" >안녕하세요. 손님</p>
</body>
</html>

웹페이지에서 < 안녕하세요. hello!! > 가 보여짐

 


 

5강 : 빌드하고 실행하기

 

(윈도우 기준) 커맨드라인 기반, 프로젝트 폴더 위치에서 gradlew build 실행

build 완료되면

build/libs 이동 후 java -jar 명령으로 파일 실행

완료. localhost:8080 접근 가능

 

서버 배포할때는 .jar 파일만 복사해서 넣어주면 됨. 매우 편리해진것임!!

gradlew clean (build)

 

 


 

6강 : 스프링 웹 개발 기초

 

* 정적 컨텐츠 - (그냥 전달)

  • static 패키지에 html 파일 넣고 hello.html 로 접근하면 됨.
  • 웹브라우저 요청 - 내장톰캣서버가 요청 받음 - 스프링 컨테이너가 hello 관련 컨트롤러가 있는지 찾아봄(우선순위 높음) - 없으면 static에 가서 hello.html이 있는지 찾아봄 - 있으면 웹브라우저에 바로 반환

 

 

* MVC와 템플릿 엔진 - (JSP, PHP)

  • Model - View - Controller
  • 3권 분립, 각자의 역할에 최대한 충실히

   viewResolver가 thymeleaf에게 html변환 요청 후 넘김

   

 

* API - (json 구조 포맷으로 전달하는 것의 요즘 api)

  • 제일 많이 씀. 기본
  • @ResponseBody - view 이런거 없이 그냥 그대로 client에게 내려감. 따라서 html 형식도 아닌 플레인 데이터
  • 객체를 리턴하면 key, value 구조 json으로
  • viewResolver 대신 HttpMessageConverter (단순 문자열 -> StringConverter, 객체 -> JsonConverter 리턴)
  •  

 

( Ctrl + Shift + Enter = > 문장 완성시켜줌)

( Alt + Insert => Generate 단축어)

 

 


 

7강 - 비즈니스 요구사항 정리

 

아직 데이터 저장소가 선정되지 않음 (가상의 시나리오)

 

컨트롤러 : 웹 MVC의 컨트롤러 역할

서비스 : 핵심 비즈니스 로직 구현

리포지토리 : 데이터베이스에 접근, 도메인 객체를 DB에 저장하고 관리

도메인 : 비즈니스 도메인 객체

 

 


 

8강 -  회원 도메인과 리포지토리 만들기

 

Optional<>  null로 감싸서 반환 - return Optional.ofNullable(store.get(id));

 

 

package hello.hellospring.repository;

import hello.hellospring.domain.Member;

import java.util.*;

public class MemoryMemberRepository implements MemberRepository{

    private static Map<Long, Member> store = new HashMap<>();
    private static long sequence = 0L;

    @Override
    public Member save(Member member) {
        member.setId(++sequence);
        store.put(member.getId(), member);
        return member;
    }

    @Override
    public Optional<Member> findById(Long id) {
        return Optional.ofNullable(store.get(id));
    }

    @Override
    public Optional<Member> findByName(String name) {
        return store.values().stream()
                .filter(member -> member.getName().equals(name))
                .findAny();

    }

    @Override
    public List<Member> findAll() {
        return new ArrayList<>(store.values());

    }
}

 

 

 


 

 

9강 - 회원 리포지토리 테스트 케이스 작성

 

볼 때 마다 기분좋은 초록색. 깃허브 잔디와 동급이다

 

return value가 Optional 일때, 값을 꺼낼때는 .get()으로 꺼낼 수 있음

import static org.assertj.core.api.Assertions.assertThat;
...
...
...
Member result = repository.findById(member.getId()).get();
assertThat(result).isEqualTo(member);

 

 

(Shift + F6 => rename을 한꺼번에 해줌

 

 

 

테스트간에는 순서가 보장되지 않음.

매 테스트마다 클리어하는 코드를 넣어줘야함

    @AfterEach
    public void afterEach() {
        // 클리어하는 코드
    }

구현과 테스트를 반대로?  ->  TDD

< test코드 없이 개발하는건 사실 불가능함 >

 

 

 


 

 

10강 - 회원 서비스 개발

 

Service 패키지 - MemberService 생성

 

회원가입, 회원조회

 

(Ctrl + Alt + V => return 값에 맞춰 왼쪽에 변수 생성해줌)

 

.ifPresent()

 

 

 


 

 

11강 - 회원 서비스 테스트

 

 

given 

when

then 기법

 

정상플로우도 중요하지만 예외가 터지는 것도 봐야한다. 

assertThrows() 

 

dependency injection