6. Controller (프레젠테이션 계층)
- 정의: 클라이언트(브라우저, 모바일 앱 등)의 HTTP 요청을 가장 먼저 맞이하는 입구. 요청 데이터를 검증하고, 알맞은 Service(주방)로 작업을 위임한 뒤 그 결과를 포장하여 응답하는 역할. (💡 실무 원칙: 컨트롤러 안에는 복잡한 비즈니스 로직이 들어가면 안 됨)
- @Controller vs @RestController:
- @Controller: 주로 서버에서 화면(HTML, Thymeleaf 등)을 직접 렌더링해서 페이지(View)의 경로를 반환할 때 사용. (SSR 방식)
- @RestController: 화면 없이 **데이터(JSON)**만 반환하는 REST API 서버에서 사용. 내부적으로 @Controller와 JSON 변환을 지시하는 @ResponseBody가 합쳐진 형태. (CSR 방식)
- 요청 데이터를 꺼내는 핵심 어노테이션:
- @RequestBody: HTTP 본문(Body)에 담긴 JSON 데이터를 Request DTO로 변환하여 받음. (주로 POST, PUT)
- @PathVariable: URL 경로 중간에 뚫려 있는 변수를 추출함. (예: /api/orders/{orderId})
- @RequestParam: URL 끝에 물음표(?)로 붙어오는 쿼리 파라미터를 추출함. (예: 페이징 ?page=1&size=10)
- 보안 정보의 우아한 활용 (@AuthenticationPrincipal):
- Spring Security를 통과하여 SecurityContext(VIP 라운지)에 저장된 **현재 로그인 유저의 정보(UserDetails / PrincipalDetails)**를 파라미터로 즉시 주입받는 어노테이션.
- 이 덕분에 토큰이나 세션에서 ID를 직접 파싱하거나 DB를 추가로 조회할 필요 없이, 즉시 유저의 식별자(ID)를 꺼내어 Service로 넘겨줄 수 있음.
7. REST API 설계 원칙 (Controller 내부)
- 정의: 클라이언트와 서버가 HTTP 통신을 할 때, 누구나 목적을 쉽게 알아볼 수 있도록 자원(Resource)과 행위(Action)를 명확히 분리하여 통신하는 설계 방법론. 주로 JSON 형태로 데이터를 주고받음.
- URI 명명 규칙 (국룰):
- 자원을 표현할 때는 동사 대신 명사를 사용한다. (행위는 URI가 아니라 HTTP 메서드로 표현해야 함)
- 단수형 대신 복수형을 사용한다.
- (✅ 올바른 예: /api/users/1, ❌ 잘못된 예: /api/getUser/1)
- HTTP 메서드 (행위의 분리):
- GET : 데이터 조회 (Read)
- POST : 데이터 생성 (Create)
- PUT / PATCH : 데이터 수정 (Update - PUT은 전체 덮어쓰기, PATCH는 일부 수정)
- DELETE : 데이터 삭제 (Delete)
- 스프링 컨트롤러 매핑 어노테이션:
- @RequestMapping: 클래스 단에 붙여 해당 컨트롤러의 공통 URI 경로를 지정함. (예: @RequestMapping("/api/orders"))
- @GetMapping, @PostMapping 등: 각 메서드에 붙여 HTTP 요청 방식에 따라 알맞은 로직으로 길을 안내(라우팅)함.
- @ResponseBody: 서버가 반환하는 자바 객체를 JSON 형식으로 변환해 응답함. (단, 클래스에 @RestController를 붙이면 모든 메서드에 이 기능이 자동 적용되므로 생략 가능)
8. 추가 핵심 기술: 리플렉션 (Reflection)
- 정의: 구체적인 클래스 타입을 알지 못하더라도, 클래스의 이름만 알면 그 클래스의 내부 정보(메서드, 필드, 어노테이션 등)에 접근하고 객체를 강제로 생성할 수 있게 해주는 자바(Java)의 기본 API (java.lang.reflect).
- 작동 시점 (가장 중요 ⭐): 코드를 컴파일하는 '빌드 시점'이 아니라, 프로그램이 실제로 실행 중인 **'런타임(Runtime)'**에 동적으로 작동함.
- 스프링 부트 & JPA에서의 활용:
- 스프링 빈 생성자: 스프링이 켜질 때, 리플렉션을 통해 모든 클래스를 스캔하여 @Controller, @Service 등이 붙은 클래스를 찾아냄. 이후 런타임에 알아서 객체(Bean)를 생성하고 의존성을 주입해 줌.
- JPA 엔티티 생성: JPA가 DB에서 가져온 데이터를 자바 객체로 만들 때, 리플렉션을 사용해 기본 생성자(@NoArgsConstructor)로 빈 껍데기 객체를 먼저 만든 뒤 private 필드에 값을 직접 꽂아 넣음.
9. 설정 파일들 (프로젝트의 뼈대와 제어판)
- build.gradle (의존성 관리): 프로젝트 빌드 시 필요한 외부 라이브러리(기술)들을 추가하고 관리하는 파일. (implementation으로 추가하면 전 세계 저장소에서 알아서 다운로드해 줌)
- application.yml (통합 제어 패널): 프로젝트의 모든 환경 변수를 통제하는 곳. DB 연결 정보, JPA 설정(ddl-auto), 포트 번호 등을 설정함. (로컬용과 운영 서버용을 분리하는 Profile 기능도 여기서 관리)
- @Configuration (자바 기반 설정): .yml 파일의 텍스트만으로는 부족할 때, 자바 코드를 통해 복잡한 객체(Bean)를 조립해서 스프링에 미리 세팅해 두는 클래스. (Security, WebClient, 비동기 설정 등)
- .gitignore (보안 투명 망토): Git(GitHub)에 코드를 올릴 때 절대 올라가면 안 되는 파일들의 목록을 적어두는 곳. (DB 비밀번호, JWT 시크릿 키 등이 담긴 설정 파일이나 빌드 결과물을 누출로부터 방어)
10. Spring Security와 UserDetails
- 정의: 스프링 기반 애플리케이션의 인증(Authentication, 누구인지 확인)과 인가(Authorization, 권한이 있는지 확인)를 전담하는 강력한 보안 프레임워크.
- 전통적인 인증 처리 아키텍처 (흐름):
- 클라이언트의 HTTP 요청이 들어오면 Filter(AuthenticationFilter 등)가 이를 가로챔.
- 필터는 검증을 **AuthenticationManager**에게 위임하고, 매니저는 다시 실제 검증을 수행할 **AuthenticationProvider**에게 넘김.
- Provider는 **UserDetailsService**를 호출하여 DB에서 실제 유저 정보를 조회하고 대조함.
- 인증이 성공하면 이 유저의 최종 인증 객체(Authentication)를 서버의 VIP 라운지인 **SecurityContextHolder**에 저장함.
- 로그인 유지 방식의 두 갈래:
- Form Login (세션 기반): 서버가 메모리(방명록)에 유저의 세션을 저장하고, 클라이언트(쿠키)에게는 세션 ID만 발급하는 전통적 방식.
- JWT (토큰 기반): 서버는 상태를 저장하지 않고(Stateless - 기억상실증), 유저의 데이터와 서버의 '위조 방지 서명'이 담긴 토큰을 발급. 클라이언트가 이 토큰을 보관하며, 요청 시 서버는 서명만 대조하여 검증함.
- SecurityConfig의 역할: 전체 보안 교통정리. CSRF 공격 방어 설정(켜기/끄기), URL 경로별 접근 권한(누구나 접근 가능한 permitAll vs 로그인해야 하는 authenticated), 로그인 페이지 등록 등을 통제함.
- UserDetails와 컨트롤러 연동 (@AuthenticationPrincipal):
- UserDetails: 스프링 시큐리티가 이해할 수 있는 유저 정보의 '표준 규격'.
- PrincipalDetails: 우리의 실제 유저 엔티티를 이 표준 규격에 맞게 감싸는 일종의 포장지(Adapter).
- 인증 과정을 통과해 이 포장지가 SecurityContextHolder에 안착하면, Controller에서는 @AuthenticationPrincipal 어노테이션 하나만으로 굳이 DB를 다시 뒤지지 않고도 로그인한 유저의 정보를 즉시 꺼내서 사용할 수 있음.
'개발 공부 > 스프링' 카테고리의 다른 글
| 순수 Java로 WAS 구현해보기 (1) - 스프링과 WAS의 핵심 개념 이해 (1) | 2026.04.06 |
|---|---|
| SpringApplication에 대한 정리 (0) | 2026.03.25 |
| 백엔드 계층 구조 정리 1 (0) | 2026.03.11 |
| 스프링 기초 (0) | 2026.02.17 |
| 스프링 정리 (0) | 2026.02.16 |