스프링에서 @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 응답을 혼합하여 사용하고 싶을 때 적합합니다.
'방구석 컴퓨터 > 방구석 스프링' 카테고리의 다른 글
스프링 시큐리티 - 기본 인증 프로세스 (0) | 2024.11.21 |
---|---|
JPA, JDBC (4) | 2024.11.20 |
구글 플레이 인앱 결제와 영수증 처리 프로세스 (2) | 2024.10.30 |
스프링 시큐리티 Basic Auth (0) | 2023.12.07 |
스프링 시큐리티와 JPA를 활용한 Basic Auth (0) | 2023.12.06 |