@RestController

반응형

스프링에서 @RestController는 RESTful 웹 서비스 개발을 위한 컨트롤러를 제공하며, 클라이언트에게 데이터를 JSON 또는 XML 형식으로 응답하는 데 사용됩니다.

@RestController의 역할

`@RestController`는 `@Controller`와 `@ResponseBody`를 결합한 어노테이션입니다.

결과적으로, 모든 메서드의 반환값은 HTTP 응답 본문(body)에 직렬화(Serialization)되어 클라이언트로 전달됩니다.

이를 통해 JSON 또는 XML 형식으로 데이터를 바로 반환할 수 있습니다.

직렬화: 객체나 데이터 구조를 파일, 메모리, 네트워크 등으로 전송하거나 저장하기 위해 연속적인 바이트 형태로 변환하는 과정 (ex. 자바 객체 > JSON, XML, 바이너리 형식 등)

역직렬화: 직렬화된 데이터를 다시 객체나 데이터 구조로 복원하는 과정 (ex. JSON, XML > 자바 객체)

데이터 응답 프로세스

1. 메서드 반환값 준비

 

컨트롤러 메서드에서 객체를 반환합니다.

반환값은 보통 자바 객체, List, Map, 또는 기본 자료형입니다.

@RestController
@RequestMapping("/api")
public class ExampleController {

    @GetMapping("/example")
    public User getExample() {
        return new User("John", "Doe", 30);
    }

    static class User {
        private String firstName;
        private String lastName;
        private int age;
    }
}

 

2. 직렬화

 

반환된 객체는 HttpMessageConverter에 의해 JSON 또는 XML과 같은 포맷으로 직렬화됩니다.

  • 스프링은 기본적으로 `Jackson` 라이브러리를 사용해 JSON 형식으로 변환합니다.
  • 요청 헤더의 `Accept` 필드에 따라 출력 포맷(JSON/XML)이 결정됩니다. ( Spring은 Accept 헤더를 기반으로 요청을 분석하고 적절한 형식으로 데이터를 반환합니다.)

위에 간략한 코드를 바탕으로 예시를 보여드리면

 

JSON 응답일 때는 헤더와 응답값의 형태는 아래와 같습니다.

// 헤더 Accept 필드
Accept: application/json
{
    "firstName": "John",
    "lastName": "Doe",
    "age": 30
}

 

XML 응답일 때의 헤더와 응답값의 형태는 아래와 같습니다.

Accept: application/xml
<User>
    <firstName>John</firstName>
    <lastName>Doe</lastName>
    <age>30</age>
</User>

 

3. HTTP 응답 생성

 

직렬화된 데이터가 HTTP 응답의 본문(body)에 포함되고, 상태 코드( ex. 200 OK)와 함께 클라이언트로 전송됩니다.


이러한 응답 프로세스에서 사용되는 스프링의 주요 구성요소들이 크게 3가지가 있습니다.

  • `@RestController`
    • RESTful 방식으로 데이터를 반환하는 컨트롤러 클래스 선언
  • `@RequestMapping` 또는 HTTP 메서드 매핑 어노테이션
    • 클라이언트 요청을 특정 메서드에 매핑
    • ex) `@GetMapping`, `@PostMapping`, `@PutMapping`, `@DeleteMapping`
  • `HttpMessageConverter`
    • 반환값을 JSON/XML 등으로 직렬화
    • 스프링 부트에서는 'MappingJackson2HttpMessageConverter`가 기본으로 설정되어 JSON 처리를 담당합니다.

추가적으로 HTTP 응답에 대해서 조금 더 세분화적인 커스터마이징도 가능한데요.

 

1) `ResponseEntity`를 사용한 HTTP 상태 코드나 헤더를 세부적으로 제어

 

우선 `ResponseEntity.status`를 사용해서 간편하게 HTTP 응답 코드를 설정할 수 있습니다.

@GetMapping("/response")
public ResponseEntity<Map<String, String>> getCustomResponse() {
    Map<String, String> body = new HashMap<>();
    body.put("message", "Custom Response");
    return ResponseEntity.status(HttpStatus.CREATED).body(body);	// HTTP 응답 코드 설정
}

 

또 아래와 같이 헤더에 원하는 필드를 추가할 수도 있습니다.

@GetMapping("/response")
public ResponseEntity<Map<String, String>> getCustomResponse() {
    // 응답 본문 데이터
    Map<String, String> body = new HashMap<>();
    body.put("message", "Custom Response");

    // 응답 헤더 설정
    HttpHeaders headers = new HttpHeaders();
    headers.add("Custom-Header", "CustomValue");
    headers.add("Content-Type", "application/json");

    // ResponseEntity로 응답 구성
    return new ResponseEntity<>(body, headers, HttpStatus.CREATED);
}

 

`HttpHeaders` 객체를 생성하고 `add()` 메서드를 통해 원하는 헤더를 추가합니다.

그리고 `ResponseEntity`의 세 가지 매개변수를 통해 응답을 구성합니다.

  • 본문(body): 전달한 본문 객체를 설정
  • 헤더(headers): `HttpHeaders` 객체를 전달
  • 상태 코드(status): `HttpStatus`의 코드를 전달

 

이렇게 하면 아래와 같이 커스텀 헤더가 함께 응답이 오는데요.

HTTP/1.1 201 Created
Content-Type: application/json
Custom-Header: CustomValue

{
    "message": "Custom Response"
}

 

이러한 헤더 제어를 통해

 

1. 사용자 지정 헤더 전달 가능: 특정 클라이언트 요구사항을 충족하거나 API의 특수한 정보를 전달할 때 사용

2. CORS 설정: `Access-Control-Allow-Origin`, `Access-Control-Allow-Methods` 같은 헤더를 설정

3. 캐싱: `Cache-Control`이나 `Expires`와 같은 헤더로 클라이언트 캐싱 동작 제어

 

와 같은 기능들을 사용할 수 있습니다.

 

 

2) JSON 응답 형식 커스터마이징

`@JsonProperty` 또는 `@JsonIgnore` 애노테이션을 사용해 JSON 형식을 변경할 수 있습니다.

class User {
    @JsonProperty("custom_name") //JSON 필드 이름을 원하는대로 변경
    private String firstName;

    @JsonIgnore
    private String password; // JSON 응답에 포함되지 않음
}

 


사실 `@RestController`는 `@Controller` + `@ResponseBody`와 같다고 생각하면 되는데요.

 

`@RestController`는 모든 메서드의 반환값이 자동으로 HTTP 응답 본문(body)에 직렬화됩니다.

그렇기 때문에 더 간결하고 RESTful 서비스를 작성할 때 유용합니다.

 

`@Controller`는 기본적으로 뷰(View)를 반환하는데 사용됩니다.

그래서 메서드 반환값을 HTTP 응답 본문으로 보내려면 반드시 `@ResponseBody`를 추가해야 합니다.

@Controller
@RequestMapping("/api")
public class ExampleController {

    @GetMapping("/example")
    @ResponseBody
    public String getExample() {
        return "Hello, World!";
    }
}

 

MVC 패턴에서 뷰와 JSON 응답을 혼합하여 사용하고 싶을 때 적합합니다.

반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유