1. HTTP 요청과 응답 구조 개요
Spring Boot 기반의 웹 애플리케이션은 HTTP 요청(Request)을 받고, 그에 대한 적절한 응답(Response)을 클라이언트에게 반환한다. HTTP 메시지는 크게 Start Line, Headers, Body로 구성된다.
✅ 요청(Request)
- Start Line: 요청의 핵심 정보
- HTTP 메서드: GET, POST, PUT, DELETE 등
- Request Target: 요청 대상 URI
- HTTP 버전: 예) HTTP/1.1
- Headers: 요청과 관련된 메타데이터 (ex. Content-Type, Authorization)
- Body: POST나 PUT 같은 요청에서 클라이언트가 보내는 데이터 (JSON, 폼 데이터 등)
✅ 응답(Response)
- Status Line: HTTP 버전 + 상태 코드 + 텍스트
- 예: HTTP/1.1 200 OK
- Headers: Content-Type, Cache-Control 등 응답 메타데이터
- Body: 실제로 클라이언트에게 전달될 JSON 등
2. 스프링에서의 응답 정형화
프론트엔드와의 협업이나 유지보수성을 고려할 때, 응답 형식을 일관되게 설계하는 것이 매우 중요하다. 이때 주로 사용하는 것이 ResponseEntity와 ResponseDto이다.
📌 ResponseEntity
ResponseEntity는 HTTP 상태 코드, 헤더, 바디 모두를 조작할 수 있는 클래스다. 보통 컨트롤러에서 직접 응답의 상태나 구조를 커스터마이징하고 싶을 때 사용한다.
return ResponseEntity.status(HttpStatus.CREATED)
.body(new ResponseDto<>(HttpStatus.CREATED.value(), "등록 성공", data));
📌 ResponseDto
비즈니스 로직에서 반환하는 데이터가 어떤 구조든 간에, 프론트엔드에서는 일관된 응답을 원한다. 따라서 우리는 다음과 같은 공통 ResponseDto를 만든다:
@Getter @AllArgsConstructor
public class ResponseDto<T> {
private int status;
private String message;
private T data;
}
3. 사용자 입력 검증: Spring Boot Validation
프론트에서 넘어오는 데이터를 백엔드에서 철저히 검증하지 않으면 DB 무결성이 깨지고, 보안 문제도 발생할 수 있다. 이를 방지하기 위해 jakarta.validation 기반의 어노테이션 기반 Validation을 활용한다.
✨ 대표 어노테이션 예시
- @NotNull: null 불가
- @NotEmpty: null & 빈 문자열 모두 불가
- @NotBlank: 공백 포함 문자열도 불가
- @Size(min = 2, max = 20): 문자열 길이 제한
- @Email: 이메일 형식 확인
- @Pattern(regexp = "^[a-zA-Z0-9]+$"): 정규표현식
- @Future, @Past: 날짜 조건
이러한 어노테이션은 DTO 클래스에서 필드에 직접 선언한다.
public class UserRequestDto {
@NotBlank(message = "이름은 필수 항목입니다.")
private String name;
@Email(message = "올바른 이메일 형식이 아닙니다.")
private String email;
@Size(min = 8, max = 20)
private String password;
}
4. 예외 처리까지 연결된 Validation 흐름
Spring Boot에서는 @Valid를 사용하여 DTO에 선언한 검증 조건을 자동으로 실행할 수 있다. 예외가 발생하면 MethodArgumentNotValidException을 통해 잡히고, 이를 @RestControllerAdvice로 글로벌하게 처리할 수 있다.
@PostMapping("/register")
public ResponseEntity<ResponseDto<Void>> register(
@RequestBody @Valid UserRequestDto requestDto) {
userService.register(requestDto);
return ResponseEntity.ok(new ResponseDto<>(200, "회원가입 성공", null));
}
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ResponseDto<Void>> handleValidationException(MethodArgumentNotValidException ex) {
String errorMessage = ex.getBindingResult().getFieldError().getDefaultMessage();
return ResponseEntity.badRequest().body(new ResponseDto<>(400, errorMessage, null));
}
}'웹개발 > SpringBoot' 카테고리의 다른 글
| Security (0) | 2025.05.27 |
|---|---|
| Rest API (1) | 2025.05.26 |
| @Bean VS @Component (0) | 2025.05.24 |
| Controller Mapping Annotation (0) | 2025.05.23 |
| Jpa Repository (0) | 2025.05.22 |