'스프링 프레임워크 첫걸음' 책을 읽고 배운 개념 중 요청 파라미터와 관련된 부분을 정리했습니다 💭
요청 파라미터는 사용자가 웹 페이지의 폼에 데이터를 입력해서 제출할 때 서버로 전송되는 데이터를 말합니다. 예를 들어, 사용자가 입력한 이름, 나이를 요청 파라미터라고 부릅니다.
서버가 클라이언트의 요청을 이해하고, 그에 맞는 응답을 주기 위해서 요청 파라미터가 사용됩니다. 이처럼 클라이언트가 서버에 무언가 요청을 보내려고 할 때는 여러 방법을 통해 데이터를 전송할 수 있습니다.
요청 방법이 어떤 형태로 올 수 있는지 분류하면 아래와 같습니다.
✅ 쿼리 스트링 (query string): URL에서 '?'뒤에 붙는 파라미터를 의미하며, 주로 GET 요청에서 사용합니다. 검색어나 특정 페이지 요청에서 볼 수 있습니다.
// 사용자 입력을 토대로 아래 URL이 생성되었다고 가정
// https://bookstore.com/search?query=bookList&page=1
// GET 요청을 처리하는 핸들러 메소드
@GetMapping("/search")
public String search(@RequestParam("query") String query, @RequestParam("page") int page) {
// 요청 파라미터를 처리할 로직 작성
return "searchResults";
}
✅ 요청 본문 (request body): HTTP 요청 본문에 포함되는 데이터를 의미하며, 주로 POST, PUT 요청에 사용합니다. JSON 형태의 Form Data도 본문에 포함해서 보낼 수 있습니다.
// 회원 가입 폼을 요청 본문에 포함해서 전송
public class SignUpController {
private final SignUpService service;
// POST 요청을 처리하는 핸들러 메소드
@PostMapping("/signup")
public ResponseEntity<String> signUpUser(@RequestBody SignUpForm form) {
return ResponseEntity.ok(service.signUpUser(form));
}
}
✅ 뷰에서 클릭한 버튼의 value 값: HTML 폼의 여러 버튼 중에서 사용자가 클릭한 버튼이 무엇인지 할기 위해 사용되는 파라미터를 의미합니다.
<!-- 타임리프를 사용한 예시 -->
<body>
<form th:action="@{/submit}" method="post">
<input type="text" name="username" placeholder="Enter username">
<button type="submit" name="action" value="save">Save</button>
<button type="submit" name="action" value="delete">Delete</button>
</form>
</body>
클라이언트가 클릭한 버튼의 value 값이 /submit 경로를 통해 @RequestParam을 사용하여 파라미터로 서버에 전송되면 요청 핸들러 메소드가 이를 처리합니다.
✅ 경로 변수 (path variable): URL 경로의 일부로 포함되어 전송되는 파라미터를 의미합니다. @PathVariable 어노테이션을 사용해 값을 전송합니다.
https://example.com/users/123 여기서 123이 경로 변수입니다.@RequestParam 과 @PathVariable의 차이
• @RequestParam: URL 뒤에 오는 쿼리 스트링에서 값을 받아옴 (?name=John).
• @PathVariable: URL 경로 자체에서 동적으로 값을 받아옴 (/greet/John).
-> 둘 다 URL에서 값을 받지만,어디에서 값을 추출하는지에 따라 차이가 있습니다.
폼 클래스는 위의 방식들로 전달된 요청 파라미터를 담기 위해서 서버 쪽에 정의된 자바 클래스를 뜻합니다. 폼 클래스를 사용하면 사용자가 입력한 데이터를 캡슐화해서 묶어둘 수 있다는 장점이 있습니다.
// form 클래스 예시
public class form {
private String name;
private Integer age;
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
private LocalDate birthday;
}
사용자가 데이터를 입력하면 해당 내용을 수집해서 폼 클래스 객체에 바인딩합니다. 폼 클래스는 해당 데이터가 유효한지 검사하고, 유효하다면 비즈니스 로직으로 전달합니다.
@RequestBody 사용: @RequestBody 어노테이션은 사용자가 웹사이트에서 폼을 작성해서 제출한 데이터를 JSON 형식으로 서버에 전송합니다. 이 JSON 데이터를 자바 객체인 Form 클래스로 변환해서 사용하게 됩니다.Model 사용: 서버에서 Form 클래스를 이용해서 데이터를 준비한 후, 이 데이터를 Model에 담습니다. (Model은 Spring MVC 패턴에서 데이터 전달을 담당하는 객체) Model에 담긴 데이터는 뷰 템플릿인 html 템플릿으로 전달되어, 최종적으로 사용자가 볼 수 있는 웹 페이지가 만들어집니다.유효성 검사는 입력된 데이터에 문제가 있는지 확인하고 필요하면 사용자에게 피드백을 제공할 수 있는 방법입니다.
(1) 컨트롤러가 유효성 검사를 뷰로 전달하여 뷰에서 오류 메시지를 사용자에게 표시하는 방식이 있고, (2) @RestControllerAdvice와 @ExceptionHandler를 사용해서 전역적으로 (중앙에서 통합하여 일관된 방식으로) 예외를 처리하는 방법이 있습니다. 두 방법 모두 폼 클래스에서 유효성 검사 어노테이션을 사용해서 Spring이 자동으로 유효성 검사를 수행하도록 설정할 수 있습니다.
1번 방식은 이 검사 결과를 받아 뷰로 보내고, 2번 방식은 전역 예외 처리기에서 @ExceptionHandler를 사용해 사용자에게 일관된 오류 응답을 보내도록 설정할 수 있습니다.
아래는 폼 클래스에서 유효성 검사를 진행할 때 활용되는 몇 가지 어노테이션입니다.
@NotNull: null이 아닌지 체크@NotEmpty: null이거나 공백이 아닌지 체크@NotBlank: null, 공백, 스페이스, 탭이 아닌지 체크@Future, @Past: 미래나 과거 날짜인지 체크public class UserForm {
@NotBlank
private String name;
@NotNull
@Min(0)
private Integer age;
@NotNull
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
@Past
private LocalDate birthday;
@NotEmpty
private String email;
@NotNull
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
@Future
private LocalDate subscriptionEndDate;
@NotEmpty
private List<@NotBlank String> hobbies;
}