IT 강좌(IT Lectures)/SpringBoot

6강. 컨트롤러(Controller)와 라우팅(Routing)

소울입니다 2024. 7. 9. 14:22
728x90
반응형

 

챕터 6: 컨트롤러와 라우팅

6.1 Spring MVC와 @Controller

6.1.1 Spring MVC의 개념과 역할

Spring MVC(Model-View-Controller)는 웹 애플리케이션의 요청과 응답을 처리하는 프레임워크입니다. Spring MVC는 다음과 같은 역할을 합니다:

  • Model: 데이터와 비즈니스 로직을 담당
  • View: 사용자에게 데이터를 보여주는 역할
  • Controller: 사용자의 요청을 처리하고 적절한 모델과 뷰를 선택

생겨난 이유:

  • 웹 애플리케이션의 복잡성이 증가하면서, 코드의 유지보수성과 재사용성을 높이기 위해 각 계층을 분리할 필요성이 생겼습니다.
  • MVC 패턴은 이러한 요구를 충족시키며, 사용자 인터페이스 로직과 비즈니스 로직을 분리하여 개발자들이 각 계층에 집중할 수 있게 합니다.

6.1.2 @Controller 어노테이션 사용법

@Controller 어노테이션은 Spring MVC에서 컨트롤러 클래스를 정의하는 데 사용됩니다. 이 어노테이션은 해당 클래스가 웹 요청을 처리하는 역할을 한다는 것을 나타냅니다.


package com.example.demo;

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

// @Controller 어노테이션을 사용하여 이 클래스를 웹 컨트롤러로 정의
@Controller
public class MyController {

    // @GetMapping 어노테이션을 사용하여 HTTP GET 요청을 매핑
    @GetMapping("/welcome")
    public String welcome(Model model) {
        // 모델에 데이터를 추가
        model.addAttribute("message", "Welcome to Spring MVC!");
        // 뷰 이름을 반환
        return "welcome";
    }
}
    

6.2 @RequestMapping과 기타 매핑 어노테이션

6.2.1 @RequestMapping의 다양한 사용 예

@RequestMapping 어노테이션은 요청 URL과 컨트롤러 메서드를 매핑하는 데 사용됩니다. 다양한 HTTP 메서드(GET, POST, PUT, DELETE 등)에 대해 요청을 매핑할 수 있습니다.

 

생겨난 이유:

  • 웹 애플리케이션에서 다양한 HTTP 메서드를 처리하기 위해 각 메서드와 URL을 매핑할 필요성이 생겼습니다.
  • @RequestMapping은 이러한 매핑을 간단하게 정의할 수 있도록 설계되었습니다.

package com.example.demo;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

// @RestController 어노테이션을 사용하여 이 클래스를 RESTful 웹 컨트롤러로 정의
@RestController
public class RequestMappingController {

    // @RequestMapping을 사용하여 HTTP GET 요청을 매핑
    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String hello() {
        return "Hello, Spring Boot!";
    }

    // @RequestMapping을 사용하여 HTTP POST 요청을 매핑
    @RequestMapping(value = "/submit", method = RequestMethod.POST)
    public String submit() {
        return "Data submitted!";
    }

    // @RequestMapping을 사용하여 HTTP DELETE 요청을 매핑
    @RequestMapping(value = "/delete", method = RequestMethod.DELETE)
    public String delete() {
        return "Data deleted!";
    }
}
    

6.2.2 @GetMapping, @PostMapping 등 기타 매핑 어노테이션

@GetMapping, @PostMapping, @PutMapping, @DeleteMapping 등은 특정 HTTP 메서드에 대해 요청을 매핑하는 어노테이션입니다. 이들은 @RequestMapping의 단축형입니다.

 

생겨난 이유:

  • 더 직관적이고 가독성이 높은 코드를 작성하기 위해 @RequestMapping의 단축형 어노테이션이 도입되었습니다.

package com.example.demo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

// @RestController 어노테이션을 사용하여 이 클래스를 RESTful 웹 컨트롤러로 정의
@RestController
public class MappingController {

    // @GetMapping을 사용하여 HTTP GET 요청을 매핑
    @GetMapping("/greet")
    public String greet() {
        return "Greetings from Spring Boot!";
    }

    // @PostMapping을 사용하여 HTTP POST 요청을 매핑
    @PostMapping("/register")
    public String register() {
        return "Registration successful!";
    }
}
    

6.3 REST API와 @RestController

6.3.1 REST API 개념

REST(Representational State Transfer)는 웹 서비스 설계 아키텍처 중 하나로, 자원을 URI로 표현하고 HTTP 메서드를 통해 자원에 대한 CRUD(Create, Read, Update, Delete) 작업을 수행합니다. RESTful 서비스는 HTTP를 통해 클라이언트와 서버 간의 상호 작용을 단순화하고, 자원의 상태를 전송합니다.

 

생겨난 이유:

  • 웹 서비스의 상호운용성을 높이고, 클라이언트와 서버 간의 통신을 단순화하기 위해 REST 아키텍처가 도입되었습니다.
  • REST는 HTTP 프로토콜을 기반으로 하여, 웹의 기본 원칙에 맞추어 설계되었습니다.

6.3.2 @RestController 어노테이션 사용법

@RestController 어노테이션은 스프링부트에서 RESTful 웹 서비스를 구현하는 데 사용됩니다. 이 어노테이션은 @Controller와 @ResponseBody를 결합한 형태로, 모든 메서드의 반환값이 HTTP 응답 본문으로 직렬화됩니다.


package com.example.demo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

// @RestController 어노테이션을 사용하여 이 클래스를 RESTful 웹 컨트롤러로 정의
@RestController
public class RestApiController {

    // @GetMapping을 사용하여 HTTP GET 요청을 매핑
    @GetMapping("/api/welcome")
    public String welcome() {
        return "Welcome to the REST API!";
    }

    // @GetMapping을 사용하여 HTTP GET 요청을 매핑
    @GetMapping("/api/data")
    public String getData() {
        return "Here is some data!";
    }

    // @GetMapping을 사용하여 HTTP GET 요청을 매핑
    @GetMapping("/api/info")
    public String getInfo() {
        return "Here is some information!";
    }
}
    

6.4 @PathVariable과 @RequestParam 사용법

6.4.1 경로 변수와 요청 파라미터 사용 예

@PathVariable과 @RequestParam 어노테이션은 URL 경로와 요청 파라미터에서 데이터를 추출하는 데 사용됩니다.

 

생겨난 이유:

  • 클라이언트의 요청에서 동적으로 변하는 데이터를 처리하기 위해 경로 변수와 요청 파라미터를 사용합니다.
  • 이는 웹 애플리케이션에서 더 유연하고 동적인 경로 매핑을 가능하게 합니다.

예제: @PathVariable 사용


package com.example.demo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

// @RestController 어노테이션을 사용하여 이 클래스를 RESTful 웹 컨트롤러로 정의
@RestController
public class PathVariableController {

    // @PathVariable을 사용하여 URL 경로에서 데이터를 추출
    @GetMapping("/api/user/{userId}")
    public String getUser(@PathVariable("userId") String userId) {
        // URL 경로에서 추출한 userId를 사용하여 응답 생성
        return "User ID: " + userId;
    }

    // @PathVariable을 사용하여 URL 경로에서 데이터를 추출
    @GetMapping("/api/order/{orderId}")
    public String getOrder(@PathVariable("orderId") String orderId) {
        // URL 경로에서 추출한 orderId를 사용하여 응답 생성
        return "Order ID: " + orderId;
    }
}
    

예제: @RequestParam 사용


package com.example.demo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

// @RestController 어노테이션을 사용하여 이 클래스를 RESTful 웹 컨트롤러로 정의
@RestController
public class RequestParamController {

    // @RequestParam을 사용하여 요청 파라미터에서 데이터를 추출
    @GetMapping("/api/search")
    public String search(@RequestParam("query") String query) {
        // 요청 파라미터에서 추출한 query를 사용하여 응답 생성
        return "Search query: " + query;
    }

    // @RequestParam을 사용하여 요청 파라미터에서 데이터를 추출
    @GetMapping("/api/filter")
    public String filter(@RequestParam("type") String type, @RequestParam("value") String value) {
        // 요청 파라미터에서 추출한 type과 value를 사용하여 응답 생성
        return "Filter type: " + type + ", value: " + value;
    }
}
    

예제: 복합 사용 예


package com.example.demo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

// @RestController 어노테이션을 사용하여 이 클래스를 RESTful 웹 컨트롤러로 정의
@RestController
public class MixedController {

    // @PathVariable과 @RequestParam을 함께 사용하여 데이터를 추출
    @GetMapping("/api/items/{itemId}")
    public String getItem(@PathVariable("itemId") String itemId, @RequestParam("detail") String detail) {
        // URL 경로에서 추출한 itemId와 요청 파라미터에서 추출한 detail을 사용하여 응답 생성
        return "Item ID: " + itemId + ", Detail: " + detail;
    }

    // @PathVariable과 @RequestParam을 함께 사용하여 데이터를 추출
    @GetMapping("/api/products/{productId}")
    public String getProduct(@PathVariable("productId") String productId, @RequestParam("category") String category) {
        // URL 경로에서 추출한 productId와 요청 파라미터에서 추출한 category를 사용하여 응답 생성
        return "Product ID: " + productId + ", Category: " + category;
    }
}
    

6.5 @RequestBody와 @ResponseBody 사용법

6.5.1 @RequestBody 개념과 사용법

@RequestBody 어노테이션은 HTTP 요청 본문을 객체로 변환하여 컨트롤러 메서드의 파라미터로 전달하는 데 사용됩니다. 주로 JSON이나 XML 데이터를 처리하는 RESTful 웹 서비스에서 사용됩니다.

 

생겨난 이유:

  • 클라이언트가 서버로 JSON이나 XML 형식의 데이터를 전송할 때, 이를 객체로 변환하여 처리할 필요가 있었습니다.
  • @RequestBody는 이러한 데이터 변환을 자동으로 처리하여 개발자의 작업을 단순화합니다.

예제: @RequestBody 사용


package com.example.demo;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

// 데이터 모델 클래스
class User {
    private String name;
    private int age;

    // Getter와 Setter
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

// @RestController 어노테이션을 사용하여 이 클래스를 RESTful 웹 컨트롤러로 정의
@RestController
public class RequestBodyController {

    // @RequestBody를 사용하여 HTTP 요청 본문을 객체로 변환
    @PostMapping("/api/users")
    public String createUser(@RequestBody User user) {
        // 요청 본문에서 변환된 User 객체를 사용
        return "User created: " + user.getName() + ", age: " + user.getAge();
    }
}
    

6.5.2 @ResponseBody 개념과 사용법

@ResponseBody 어노테이션은 컨트롤러 메서드의 반환값을 HTTP 응답 본문으로 변환하는 데 사용됩니다. 주로 JSON이나 XML 형식의 데이터를 클라이언트에게 반환할 때 사용됩니다.

 

생겨난 이유:

  • 서버에서 클라이언트로 JSON이나 XML 형식의 데이터를 전송할 때, 객체를 문자열로 변환하여 HTTP 응답 본문에 포함시킬 필요가 있었습니다.
  • @ResponseBody는 이러한 변환을 자동으로 처리하여 개발자의 작업을 단순화합니다.

예제: @ResponseBody 사용


package com.example.demo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

// 데이터 모델 클래스
class Product {
    private String id;
    private String name;

    // 생성자
    public Product(String id, String name) {
        this.id = id;
        this.name = name;
    }

    // Getter
    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }
}

// @RestController 어노테이션을 사용하여 이 클래스를 RESTful 웹 컨트롤러로 정의
@RestController
public class ResponseBodyController {

    // @ResponseBody를 사용하여 객체를 JSON 형식으로 변환
    @GetMapping("/api/products")
    @ResponseBody
    public Product getProduct() {
        // Product 객체를 생성하여 반환
        return new Product("1", "Laptop");
    }
}
    

6.6 @ModelAttribute 사용법

6.6.1 @ModelAttribute 개념과 사용법

@ModelAttribute 어노테이션은 HTTP 요청 파라미터를 바인딩하여 모델 객체로 변환하고, 이를 컨트롤러 메서드의 파라미터로 전달하는 데 사용됩니다. 주로 폼 데이터를 처리하거나 모델 데이터를 뷰에 전달할 때 사용됩니다.

 

생겨난 이유:

  • 웹 애플리케이션에서 폼 데이터를 처리하고, 모델 데이터를 뷰에 전달하기 위해 데이터 바인딩을 간편하게 할 필요가 있었습니다.
  • @ModelAttribute는 이러한 데이터 바인딩을 자동으로 처리하여 개발자의 작업을 단순화합니다.

예제: @ModelAttribute 사용


package com.example.demo;

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

// 데이터 모델 클래스
class User {
    private String name;
    private int age;

    // Getter와 Setter
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

// @Controller 어노테이션을 사용하여 이 클래스를 웹 컨트롤러로 정의
@Controller
public class ModelAttributeController {

    // @ModelAttribute를 사용하여 HTTP 요청 파라미터를 모델 객체로 바인딩
    @PostMapping("/submitUser")
    public String submitUser(@ModelAttribute User user, Model model) {
        // 모델 객체를 뷰에 추가
        model.addAttribute("user", user);
        // 뷰 이름을 반환
        return "userView";
    }
}
    

6.7 @ExceptionHandler 사용법

6.7.1 @ExceptionHandler 개념과 사용법

@ExceptionHandler 어노테이션은 컨트롤러에서 발생하는 예외를 처리하는 데 사용됩니다. 특정 예외가 발생했을 때 이를 처리하여 적절한 응답을 반환할 수 있습니다.

 

생겨난 이유:

  • 웹 애플리케이션에서 예외가 발생했을 때 이를 효과적으로 처리하고, 사용자에게 적절한 응답을 제공하기 위해 예외 처리를 간편하게 할 필요가 있었습니다.
  • @ExceptionHandler는 이러한 예외 처리를 자동으로 처리하여 개발자의 작업을 단순화합니다.

예제: @ExceptionHandler 사용


package com.example.demo;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

// 사용자 정의 예외 클래스
class CustomException extends RuntimeException {
    public CustomException(String message) {
        super(message);
    }
}

// @RestController 어노테이션을 사용하여 이 클래스를 RESTful 웹 컨트롤러로 정의
@RestController
public class ExceptionHandlerController {

    // @GetMapping을 사용하여 HTTP GET 요청을 매핑
    @GetMapping("/triggerException")
    public String triggerException() {
        // 사용자 정의 예외를 발생시킴
        throw new CustomException("Custom exception occurred!");
    }

    // @ExceptionHandler를 사용하여 CustomException을 처리
    @ExceptionHandler(CustomException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public String handleCustomException(CustomException ex) {
        // 예외 메시지를 응답으로 반환
        return ex.getMessage();
    }
}
    

예시 설명

1. @ModelAttribute:

@ModelAttribute 어노테이션은 HTTP 요청 파라미터를 바인딩하여 모델 객체로 변환하고, 이를 컨트롤러 메서드의 파라미터로 전달하는 데 사용됩니다. 주로 폼 데이터를 처리하거나 모델 데이터를 뷰에 전달할 때 사용됩니다.

이 어노테이션은 폼 데이터를 처리하고, 모델 데이터를 뷰에 전달하는 작업을 자동으로 처리하여 개발자의 작업을 단순화합니다.

 

2. @ExceptionHandler:

@ExceptionHandler 어노테이션은 컨트롤러에서 발생하는 특정 예외를 처리하는 데 사용됩니다. 예외가 발생했을 때 이를 처리하여 적절한 응답을 반환할 수 있습니다.

이 어노테이션은 예외 처리를 자동으로 처리하여 개발자의 작업을 단순화합니다.

각 개념이 생겨나게 된 이유

1. @ModelAttribute:

웹 애플리케이션에서 폼 데이터를 처리하고, 모델 데이터를 뷰에 전달하기 위해 데이터 바인딩을 간편하게 할 필요가 있었습니다. @ModelAttribute는 이러한 데이터 바인딩을 자동으로 처리하여 개발자의 작업을 단순화합니다.

이는 웹 애플리케이션에서 사용자 입력 데이터를 처리하고, 이를 뷰에 표시하는 작업을 더 쉽게 관리할 수 있게 합니다.

 

2. @ExceptionHandler:

웹 애플리케이션에서 예외가 발생했을 때 이를 효과적으로 처리하고, 사용자에게 적절한 응답을 제공하기 위해 예외 처리를 간편하게 할 필요가 있었습니다. @ExceptionHandler는 이러한 예외 처리를 자동으로 처리하여 개발자의 작업을 단순화합니다.

이는 애플리케이션의 안정성과 사용자 경험을 향상시키는 데 도움이 됩니다.

 

과거 대비 현재 사용 방식의 변화

과거에는 웹 애플리케이션에서 예외를 처리할 때, 각 메서드 내에서 개별적으로 예외를 처리해야 했습니다. 이는 많은 코드와 복잡성을 초래했습니다. @ExceptionHandler와 같은 어노테이션은 이러한 작업을 자동화하여 개발자가 더 쉽게 예외를 처리할 수 있도록 도와줍니다.

현재는 스프링부트와 같은 프레임워크가 널리 사용되며, 예외 처리와 같은 작업을 간편하게 처리할 수 있는 도구를 제공합니다. 이는 개발자가 더 적은 코드로 더 많은 기능을 구현할 수 있게 해줍니다.

이 장에서는 스프링부트 애플리케이션에서 컨트롤러와 라우팅을 구현하는 방법을 다루었습니다. 각 예제는 Spring MVC와 REST API를 사용하여 웹 요청을 처리하고 응답을 반환하는 방법을 이해하는 데 도움이 됩니다. 이를 통해 스프링부트의 컨트롤러와 라우팅 기능을 효과적으로 활용할 수 있습니다.

반응형