1. @ResponseBody란?
@ResponseBody
는 Spring MVC에서 컨트롤러 메서드가 반환하는 값을 HTTP 응답 본문으로 직렬화하여 클라이언트에게 전달할 때 사용됩니다. 반환되는 데이터는 Jackson
라이브러리를 사용하여 JSON 형식으로 변환됩니다. 기본적으로 HTTP 상태 코드는 200 OK로 설정되며, 데이터만 반환하는 단순한 API 응답 처리에 주로 사용됩니다.
1.1 @ResponseBody의 주요 특징
- JSON, XML과 같은 포맷으로 데이터를 반환
- HTTP 상태 코드는 기본적으로 200 OK
- 주로 REST API 응답에서 사용
- 뷰를 반환하지 않고 데이터를 직렬화하여 전달
2. ResponseEntity란?
ResponseEntity
는 HTTP 응답의 상태 코드, 헤더, 본문을 모두 명시적으로 제어할 수 있는 클래스로, 더 복잡한 HTTP 응답 처리가 필요할 때 사용됩니다. 단순히 본문 데이터뿐만 아니라, HTTP 상태 코드나 추가적인 응답 헤더 등을 세밀하게 구성할 수 있습니다.
2.1 ResponseEntity의 주요 특징
- 응답 본문, 헤더, 상태 코드 등을 직접 설정 가능
- 클라이언트에게 상태 코드와 함께 명확한 응답을 보낼 수 있음
- 오류 처리나 다양한 상태 코드가 필요한 API 설계에 유용
3. @ResponsBody와 ResponseEntity의 차이점
항목 | @ResponseBody |
ResponseEntity |
---|---|---|
사용 목적 | 단순히 데이터를 반환하고 싶을 때 사용 | 상태 코드, 헤더 등 응답 전체를 제어하고 싶을 때 사용 |
HTTP 상태 코드 제어 | 200 OK로 고정 (명시적 제어 어려움) | 상태 코드를 명시적으로 설정 가능 |
응답 헤더 제어 | 불가능 | 헤더를 직접 설정 가능 |
에러 처리 | 불편 | 에러 상태 코드와 메시지를 명확하게 제어 가능 |
주요 사용 사례 | 간단한 API 응답 | 복잡한 API 응답, 상태 코드와 헤더가 중요한 경우 |
4. @ResponseBody와 ResponseEntity를 이용한 회원 관련 예시 코드
아래의 예시는 회원 정보를 처리하는 간단한 API 컨트롤러를 @ResponseBody
와 ResponseEntity
를 사용하여 작성한 것입니다. 이 예시는 서비스 계층에서 회원 정보를 조회하거나 저장하는 방식으로 동작하며, 각각의 상황에 맞는 상태 코드와 헤더 등을 설정하는 방식입니다.
4.1 @ResponseBody를 사용한 컨트롤러 예시 코드
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
@ResponseBody
public User getUser(@PathVariable Long id) {
User user = userService.getUserById(id);
if (user != null) {
return user;
} else {
throw new UserNotFoundException("User not found");
}
}
@PostMapping
@ResponseBody
public User createUser(@RequestBody User user) {
return userService.saveUser(user);
}
}
위 @ResponseBody
사용 예시에서는 간단하게 회원 정보를 JSON 형식으로 반환합니다. HTTP 상태 코드는 자동으로 200 OK로 설정되며, 에러 처리를 위해서는 예외를 따로 처리해야 합니다. UserNotFoundException
같은 커스텀 예외는 별도로 처리해야 합니다.
서비스단 코드
@Service
public class UserService {
public User getUserById(Long userId) {
// DB에서 회원 정보 조회 (실제 로직은 생략)
if (userId == 1L) {
return new User(1L, "John", "Doe", "john@example.com");
} else {
return null; // 회원 정보가 없는 경우
}
}
public User saveUser(User user) {
// DB에 회원 정보 저장 (실제 로직은 생략)
user.setId(2L); // ID가 생성된 경우로 가정
return user;
}
}
4.2 ResponseEntity를 사용한 컨트롤러 예시 코드
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public ResponseEntity<?> getUser(@PathVariable Long id) {
User user = userService.getUserById(id);
if (user != null) {
// 성공적인 응답: 200 OK와 함께 사용자 정보를 반환
return ResponseEntity.ok()
.header("Custom-Header", "User found")
.body(user);
} else {
// 회원을 찾을 수 없는 경우: 404 Not Found 응답
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.header("Custom-Header", "User not found")
.body("User not found with ID: " + id);
}
}
@PostMapping
public ResponseEntity<User> createUser(@RequestBody User user) {
User createdUser = userService.saveUser(user);
// 201 Created 응답과 함께 생성된 회원 정보 반환
return ResponseEntity.status(HttpStatus.CREATED)
.body(createdUser);
}
@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<String> handleUserNotFound(UserNotFoundException ex) {
// 예외 처리: 404 상태와 에러 메시지를 반환
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(ex.getMessage());
}
}
위 예시에서는 ResponseEntity
를 사용하여 상태 코드, 헤더, 응답 본문을 명시적으로 제어하는 방식을 보여줍니다. 다음과 같은 추가적인 기능을 제공합니다.
- 사용자 정보를 성공적으로 조회했을 때 200 OK와 함께 데이터를 반환
- 사용자를 찾지 못했을 경우 404 Not Found와 함께 에러 메시지 반환
- 사용자를 생성했을 때는 201 Created 상태 코드와 생성된 회원 정보를 반환
5. 참고사항 - @RestController에서 @ResponseBody 어노테이션을 안써도 JSON형태로 반환 잘 되지않나?
@ResponseBody
는 원래 Spring MVC에서 컨트롤러 메서드의 반환 값을 HTTP 응답 본문으로 변환하는 역할을 하는 어노테이션입니다. 하지만, @RestController
는 내부적으로 @Controller
와 @ResponseBody
가 결합된 형태이기 때문에, @RestController
를 사용하는 경우에는 메서드 위에 @ResponseBody
를 명시적으로 붙이지 않아도 자동으로 JSON 또는 XML 형태로 데이터를 반환합니다.
5.1 @RestController에서의 동작 방식
@RestController
는 @Controller
+ @ResponseBody
가 포함된 어노테이션이기 때문에, 모든 메서드의 반환 값이 자동으로 JSON 형식으로 직렬화됩니다. 따라서 @RestController
가 적용된 클래스에서 메서드를 정의할 때는, @ResponseBody
를 명시적으로 붙이지 않아도 데이터는 JSON 형식으로 반환됩니다.
@RestController
어노테이션만 사용한 컨트롤러 예시 코드
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
User user = userService.getUserById(id);
if (user != null) {
return user;
} else {
throw new UserNotFoundException("User not found");
}
}
@PostMapping
public User createUser(@RequestBody User user) {
return userService.saveUser(user);
}
}
위 코드에서 @ResponseBody
를 제거했지만, 여전히 JSON 형식으로 반환됩니다. 이는 @RestController
가 자동으로 @ResponseBody
역할을 수행하기 때문입니다.
5.2 @RestController가 없는 경우
만약 @RestController
가 아닌 @Controller
를 사용한다면, 메서드의 반환 값은 뷰 이름으로 해석되어 JSP나 HTML 같은 뷰를 렌더링하려고 시도합니다. 이때 데이터를 반환하고 싶다면, @ResponseBody
를 명시적으로 추가해야 데이터가 JSON 형태로 반환됩니다
@Controller
예시 코드
@Controller
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
@ResponseBody
public User getUser(@PathVariable Long id) {
User user = userService.getUserById(id);
if (user != null) {
return user;
} else {
throw new UserNotFoundException("User not found");
}
}
@PostMapping
@ResponseBody
public User createUser(@RequestBody User user) {
return userService.saveUser(user);
}
}
6. 정리
@RestController
는 내부적으로@ResponseBody
를 포함하므로, 메서드에서 반환되는 객체는 자동으로 JSON 형식으로 직렬화되어 클라이언트에게 전달됩니다. 따라서@ResponseBody
를 명시적으로 붙일 필요가 없습니다.@Controller
를 사용하는 경우, 메서드에서 반환 값을 JSON으로 변환하여 응답하려면@ResponseBody
를 명시적으로 붙여야 합니다.
'BackEnd > Spring & JPA' 카테고리의 다른 글
[Spring] @RequestPart를 활용하여 JSON + MultipartFile 동시 전송하기 (Feat. 게시판에서 게시물 생성과 첨부 파일 업로드 한번에 처리하기) (0) | 2025.02.13 |
---|---|
[Spring Data JPA] JPA 엔티티 설계 시 생성자 접근 제한을 PROTECTED로 설정하는 이유 (0) | 2025.01.21 |
[Spring] @Controller VS @RestController (0) | 2025.01.06 |
[Spring] 스프링 개념 및 동작 원리 정리 (0) | 2025.01.05 |