Controller
Spring MVC(Model-View-Controller) 아키텍처에서 Controller는 사용자의 요청을 처리하는 역할
주요기능
- 클라이언트의 요청을 받아들이고 적절한 Service 호출
- 요청 데이터를 검증하고 처리
- 처리된 데이터를 응답으로 반환
- 예외 처리 및 에러 핸들링
동작 흐름
[Client] → [Controller] → [Service] → [Repository] → [Database] Controller는 비즈니스 로직을 직접 수행하지 않고, Service를 호출하여 데이터를 처리Spring Boot에서 Controller를 정의할 때는 @Controller 또는 @RestController 어노테이션을 사용
@Controller
JSP, Thymeleaf 등의 HTML View를 반환할 때 사용
데이터를 Model 객체에 담아서 View로 전달@Controller @RequestMapping("/user") public class UserController { @GetMapping("/profile") public String getProfile(Model model) { model.addAttribute("username", "JohnDoe"); return "profile"; // profile.html 또는 profile.jsp 반환 } }@RestController
API에서 JSON 데이터를 반환할 때 사용
@ResponseBody가 기본적으로 적용되어 HTTP 응답으로 데이터를 반환함@RestController @RequestMapping("/api/users") public class UserApiController { @GetMapping("/{id}") public ResponseEntity<User> getUser(@PathVariable Long id) { User user = new User(id, "JohnDoe", "john@example.com"); return ResponseEntity.ok(user); } }API를 만들 때는 @RestController를 사용하면 자동으로 JSON 형태로 변환됨
주요 어노테이션
@RequestMapping
컨트롤러의 기본 URL을 지정하는 역할
@RequestMapping("/users") public class UserController { }HTTP 요청을 처리하는 어노테이션
@GetMapping: Get요청 @PostMapping: POST요청 @PutMapping: PUT요청 @DeleteMapping: DELETE요청@RequestParam
@GetMapping("/") public String getUserById(@RequestParam("id") Long id) { return "User ID: " + id; }@RequestParam: 쿼리 파라미터를 받아옴 -> ?id=1 형식의 요청을 받음@PathVariable
@GetMapping("/{id}") public String getUserById(@PathVariable("id") Long id) { return "User ID: " + id; }URL 경로에서 값을 받아옴 -> /users/1 같은 URL 경로에서 값을 추출함
Service
비즈니스 로직을 처리하는 계층
주요기능
- 비즈니스 로직을 처리 (데이터 조작, 연산, 외부 API 호출 등)
- Controller와 Repository 사이에서 중재 역할 수행
- 코드의 재사용성 증가 (다른 컨트롤러에서도 동일한 로직 사용 가능)
- 데이터 검증 및 예외 처리
동작 흐름
[Client] → [Controller] → [Service] → [Repository] → [Database] Controller는 Service를 호출하고, Service는 Repository를 이용해 데이터를 처리기본 구조
Entity 클래스
@Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String email; // 기본 생성자, getter, setter }Repository
@Repository public interface UserRepository extends JpaRepository<User, Long> { }Service (비즈니스 로직)
@Service public class UserService { private final UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository = userRepository; } public List<User> getAllUsers() { return userRepository.findAll(); } public User getUserById(Long id) { return userRepository.findById(id) .orElseThrow(() -> new RuntimeException("User not found")); } public User createUser(User user) { return userRepository.save(user); } }Controller (Service를 이용해 요청 처리)
@RestController @RequestMapping("/users") public class UserController { private final UserService userService; public UserController(UserService userService) { this.userService = userService; } @GetMapping("/") public ResponseEntity<List<User>> getAllUsers() { return ResponseEntity.ok(userService.getAllUsers()); } @GetMapping("/{id}") public ResponseEntity<User> getUser(@PathVariable Long id) { return ResponseEntity.ok(userService.getUserById(id)); } @PostMapping("/") public ResponseEntity<User> createUser(@RequestBody User user) { return ResponseEntity.ok(userService.createUser(user)); } }Controller는 단순히 Service를 호출하고, 비즈니스 로직은 Service가 담당하도록 분리하는 것이 중요Service 어노테이션
@Service public class UserService { // Service 로직 구현 }@Service는 Spring의 Service 계층을 나타내는 어노테이션임 @Component의 하위 개념이며, 자동으로 빈(Bean)으로 등록됨DTO를 활용한 데이터 검증
DTO?
클라이언트와의 데이터 교환을 위한 객체
DTO를 사용하면 불필요한 엔티티 필드를 숨기고, 필요한 데이터만 주고받을 수 있다.//UserDTO public class UserDTO { private String name; private String email; public UserDTO(String name, String email) { this.name = name; this.email = email; } // Getter & Setter }//Service @Service public class UserService { private final UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository = userRepository; } public UserDTO getUserById(Long id) { User user = userRepository.findById(id) .orElseThrow(() -> new RuntimeException("User not found")); return new UserDTO(user.getName(), user.getEmail()); // DTO 변환 } }