Java가 실무에서 가장 많이 사용되는 영역은 백엔드이고,
특히 Spring Boot는 표준처럼 사용되는 프레임 워크이다.
지금까지 배운 내용들을 적용해볼 수 있는 개념이다!
기본 용어 정리
Spring:
자바 기반의 강력한 웹 애플리케이션 개발을 위한 오픈소스 프레임워크
Spring boot:
번거로운 설정 없이 간편하게 시작할 수 있는, Spring 프로젝트 템플릿 (-> 개발자가 비지니스 로직에 집중할 수 있게 해준다.)
REST API:
REST: 웹에서 데이터를 주고 받기 위한 아키텍쳐 스타일, HTTP 프로토콜을 기반, resource를 기반으로 하여 웹 서비스 간 데이터를 교한한다.
REST API: REST 원칙에 따라 설계된 웹 기반의 API (REST원칙을 잘 지킨 서비스 일 수록 유지보수와 확장성이 뛰어나다.)
REST API: REST 원칙을 다 지킨 엄격한 API
[ 스프링 웹 개발 기초 ]
기본 3가지
1. 정적 컨텐츠
2. MVC와 템플릿 엔진
MVC패턴의 view: 서버의 프로그래밍을 통해 동적으로 HTML을 랜더링하여 전달
3. API: json이라는 데이터 구조로 전달.(HTML 이용 X), 데이터만 전달하면 화면을 클라이언트에서 구성/ 서버끼리 통신하는 경우
정적 컨텐츠
1. 내장 서버에 요청 전달
2. 컨테이너에서 관련 컨트롤러(매핑된 컨트롤러)가 존재하는지 확인 (컨트롤러가 우선순위)
3. 없다면 -> static 내부의 html찾아서 반환
test는 정말 test를 위한 패키지이다.



스프링 부트 흐름

Controller: 전체를 총괄하는 감독. 요청, 요청 및 응답을 처리한다. 직접 DB에 연결을 피해 책임을 분리한다.
Service: 비지니스 로직 수행 (데이터 가공, 검증)
Repository: 데이터 베이스 접근 (CRUD 작업)
DAO와 DTO 설명: 데이터 처리의 역할 분리
DAO와 DTO는 스프링(Spring)과 같은 자바 기반 애플리케이션에서 데이터를 효율적이고 체계적으로 관리하기 위해 사용하는 핵심적인 디자인 패턴이자 개념
1. ⚙️ DAO (Data Access Object)
데이터 접근 객체, DB에 접근하는 역할을 하는 객체
주요 책임:
- DB 연결 및 해제 관리.
- CRUD 연산 수행 (Create, Read, Update, Delete). 즉, SQL 쿼리를 실행하여 DB에서 데이터를 가져오거나 저장하는 순수한 데이터 입출력 작업만 담당
- DB 접근 로직을 캡슐화하여, 다른 계층(Service, Controller)이 DB 구현 세부 사항을 알 필요 없게 함.
@Repository 어노테이션이 붙는다.
흐름 제어와의 관계: DAO는 비즈니스 로직(데이터 가공, 검증 등)을 포함 X ( 비즈니스 로직은 Service(서비스) 계층에서 처리)
오직 DB에 데이터를 요청하거나 전달하는 역할만 수행.
2. 📦 DTO (Data Transfer Object)
데이터 전송 객체. 데이터를 담아서 계층 간 전달 하는 운반체 역할.
주요 책임:
- 데이터 캡슐화: 전송해야 할 데이터를 필드(속성)에 담고, Getter/Setter 메서드를 통해 접근을 허용
- 순수한 데이터 객체: 비즈니스 로직을 가지지 않으며, 데이터 저장 및 전달 목적으로만 사용
일반적으로 Java Bean 규약을 따름. private 필드와 public Getter/Setter 메서드, 그리고 기본 생성자로 구성
🤝 DAO와 DTO의 협력
- Controller는 클라이언트로부터 받은 요청 데이터를 DTO에 담아 Service 계층으로 전달
- Service 계층은 비즈니스 로직을 수행한 후, 필요한 데이터를 DTO에 담아 DAO에 전달
- DAO는 전달받은 데이터를 바탕으로 SQL 쿼리를 만들어 DB에 접근하여 데이터를 저장하거나 조회
- DAO는 DB에서 조회한 결과를 다시 DTO 객체로 변환하여 Service 계층으로 반환하고, 최종적으로 Controller를 거쳐 클라이언트에게 응답
핵심 요약:
- DAO: '어떻게' 데이터를 가져올지 처리 (DB 접속, SQL 실행)하는 기능 객체.
- DTO: '무슨' 데이터를 전달할지 담는 데이터 객체.
MVC와 템플릿엔진 :
=> 동적인 웹 페이지를 제공한다.
=> 관심사와 책임을 분리해야한다!! MVC 패턴으로 로직과 화면을 분리하기

MVC
- Controller (로직): 웹 요청을 처리하고, 비즈니스 로직(서비스)을 수행하며, 처리 결과를 담을 데이터(Model)를 준비하는 역할
- View (화면): Controller가 준비한 데이터(Model)를 받아서 사용자에게 보여줄 최종적인 HTML 화면을 생성(렌더링) 함
- 컨트롤러의 책임: 웹 브라우저에서 들어온 HTTP 요청을 받고, 어떤 서비스가 이 요청을 처리해야 하는지 결정하고, 처리 결과를 받아 HTTP 응답으로 변환하여 반환
- DB 접근의 책임: DB에 접속하여 데이터를 조회, 저장, 수정, 삭제하는 데이터 영속성(Persistence) 관련 작업은 Repository(저장소) 계층의 책임입니다.
전체 흐름:
- 요청 받기: 웹 브라우저로부터 요청(예: 사용자 목록 조회 요청)을 받습니다.
- 데이터 전달: 이 요청을 처리하기 위해 Service(서비스) 계층을 호출합니다. (예: userService.findUsers()). 컨트롤러는 요청에 필요한 데이터를 서비스에 전달합니다.
- 결과 수신: 서비스 계층이 비즈니스 로직을 모두 수행하고 최종 결과 데이터를 컨트롤러에게 반환합니다.
- 응답 변환: 컨트롤러는 받은 데이터를 JSON 형태나 View(화면) 형태로 가공하여 웹 브라우저에 최종 HTTP 응답으로 돌려줍니다.
쉽게 비유: 컨트롤러는 매니저와 같습니다. 매니저(컨트롤러)는 클라이언트(웹 브라우저)의 주문을 받고, 그 주문을 실제로 실행할 팀원(서비스, Repository)에게 지시한 뒤, 결과물을 취합하여 클라이언트에게 전달하는 중앙 통제소 역할을 하는 것입니다.
템플릿 엔진
템플릿: HTML 구조 뼈대 (정적, 동적 부분 존재)
엔진: 작업을 자동으로 처리하고 실행 (템플릿 파일과 컨트롤러가 준비한 model을 입력받아 결합하여 최종적인 HTML문서로 변환(렌더링))

동적 흐름
- 웹브라우저 요청
- 내장 서버가 받음 -> 매칭된 컨트롤러의 메서드가 처리됨
- 컨트롤러의 반환값을 view resolver가 받아서 매핑, 템플릿엔진의 처리를 요청 / 기본 viewName 매핑 : resources:templates/ +{ViewName}+ .html
- 템플릿엔진의 랜더링(HTML)으로 변환하여 반환
- 최종반환: 렌더링한 HTML문서가 내장 서버를 거쳐 웹 브라우저로 반환
Spring boot 기본 어노테이션:
해당 코드(클래스, 메서드, 변수 등)가 어떤 역할을 해야 하는지 또는 프레임워크가 이 코드를 어떻게 처리해야 하는지를 알려준다.

스프링 부트의 핵심 원리
DI(의존성 주입):
외부(프레임 워크)에서 의존 객체를 주입 받는다. (@Autowired, 생성자 주입, Setter주입)
IoC(제어의 역전):
객체의 생성부터 생명주기 관리까지 개발자가 아닌, 프레임워크가 대신한다.
자동구성:
스프링 부트의 가장 강력한 기능. 설정을 자동으로 구성한다. (클래스경로, bean설정, 속성들을 기반으로 적절한 설정을 자동으로 설정)

#실습
실습을 하며 개념을 익혀보자.
#REST API 관련 실습

@RestController: 클래스가 REST API응답을 반환하도록 지정한다.
클래스가 문자열이나 객체를 반환하면 스프링은 이를 JSON으로 변환하여 웹 브라우저에 응답.
@RequestMapping: 웹 브라우저의 어떤 URL요청을 어떤 메서드가 처리해줄 지 연결
@RequestMapping(/web): 서버에서 /web요청이 왔을 때 hello()를 실행
URL 경로와 메서드를 매핑 (GET,POST,PUT,DELETE 등 HTTP 메소드 지정 가능하다.)
*HTTP는 데이터 전송 방식.
더 구체적인 매핑

@GetMapping(): 메소드 레벨 매핑
@PathVariable(): url의 일부를 변수처럼 받아옴.
#짱구야 안녕 실습


이름을 입력하면 내 welcome message가 화면에 나타나는 실습을 해보자!
핵심! @RequstParam 어노테이션을 사용한다.
@RequestParam
- value : 속성명 (url에서 가져올 파라미터의 이름(key) 지정)
- required : 반드시 값을 입력해야하는 속성, 기본 true (이 파라미터가 필수인지 아닌지를 결정)



springboot코드
package kr.ac.ewha.java2;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import kr.ac.ewha.java2.controller.GreetingController;
@SpringBootApplication
public class HelloSpring2Application {
private final GreetingController greetingController;
HelloSpring2Application(GreetingController greetingController){
this.greetingController=greetingController;
}
public static void main(String[] args) {
SpringApplication.run(HelloSpring2Application.class, args);
System.out.println("start!");
}
}
controller 코드
package kr.ac.ewha.java2.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import kr.ac.ewha.java2.service.GreetingService;
@RestController
public class GreetingController {
@Autowired //GreetingService 자동으로 주입
private GreetingService greetingService;
@PostMapping("/hello")
public String sayHello(@RequestParam(name="name") String name) {
System.out.println(name);
return greetingService.getGreeting(name);
}
}
service를 주입받아 실행한다. (@Autowired가 자동으로 주입해준다.)
Service코드
package kr.ac.ewha.java2.service;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;
@Service
public class GreetingService {
public String getGreeting(@RequestParam("name")String name) {
// TODO Auto-generated method stub
return "안녕하세요!"+name+" 님! 오늘도 좋은 하루 보내세용";
}
}
실행할 서비스 코드.
static html코드
<html>
<body>
<meta charset="UTF-8">
<form method="post" action="http://localhost:8080/hello",accept-charset="UTF-8">
<input type="text" name="name" value="이름을 입력하세요"/>
<button type = "submit">보내기</button>
</form>
</body>
</html>
form method를 통해 action이 발생하면 해당 url로 보낸다.
@RequestParam을 통해 url의 name을 떼온다.
@PathVariable
소감: 프로젝트와 스터디를 하면서 spring boot으 흐름을 이해할 수 있었다.