Spring에서 HTTP 요청을 다루는 주요 방법들

민준·2025년 3월 15일
post-thumbnail

1. @PathVariable

  • URL 경로의 일부를 변수로 사용할 때 사용
  • 예: /api/users/{id}/api/users/aaron
    @GetMapping("/users/{id}")
    public User getUser(@PathVariable("id") String id) {
      return userService.findUserById(id);
    }

에러 해결:

  • @PathVariable Integer id@PathVariable("id") Integer id
  • 이유: 스프링이 파라미터 이름을 인식하지 못할 수도 있기 때문.

2. @RequestParam

  • 쿼리스트링( ?key=value )로 값을 전달할 때 씀.
  • 예: /api/users?id=3
    @GetMapping("/users")
    public User getUser(@RequestParam("id") Integer id) {
        return userService.findUserById(id);
    }

옵션:

  • @RequestParam(required = false) → 필수 여부 설정
  • @RequestParam(defaultValue = "원하는 값을 String으로 명시") → 기본값 설정

3. @ModelAttribute

  • 다수의 HTTP 요청 파라미터나 multipart/form-data 형태의 파라미터를 받아 객체로 받고 싶을 때 사용.

  • 즉, @ModelAttribute는 URL의 쿼리 파라미터를 객체 필드에 값을 매핑해줌

  • 실습 코드

    • java 코드
      @PostMapping("/users")
      public User createUser(@ModelAttribute UserCreateRequestDto dto) {
      return userService.createUser(dto);
      }
    • PostMan으로 POST 요청 http://localhost:8080/users?name=Daron&age=40&job=PO
    • URL에 입력 하거나 혹은 PostMan으로 GET 요청 값이 들어갔는지 확인 http://localhost:8080/users/data?id=4

@ModelAttribute의 역할

  • 사용자의 요청 데이터를 객체로 자동 바인딩하는 역할

  • 즉, Controller에서 DTO(객체)로 변환하는 과정을 도와주는 기능!

@ModelAttribute는 기본 생성자가 필요하다 (주의사항)

  • Spring은 @ModelAttribute를 사용해서 객체를 만들 때, 객체를 생성한 후(기본 생성자로 객체 생성), setter를 이용해 값을 채워 넣음.

  • 이 때문에 @ModelAttribute를 사용할 때는 기본 생성자(@NoArgsConstructor + @Setter)가 반드시 필요

  • 만약 @Setter가 없으면?
    • @ModelAttribute가 setter를 호출할 수 없어서, 필드에 값이 들어가지 않고 null이 저장될 가능성이 큼.
  • DTO 클래스에 직접만든 생성자만 있고 기본생성자(public UserCreateRequestDto() 혹은 @NoArgsConstructor)가 없으면?
    • Spring이 기본 생성자가 없어서 객체를 만들 수 없어 에러가 발생할 수도 있음.

4. @RequestBody

  • JSON 데이터를 받아서 객체로 변환할 때 사용.

  • POST 요청에서 사용됨.

  • 예: { "name": "Daron", "age": 40, "job": "PO" }

  • 실습 코드

    • java 코드
      @PostMapping("/users")
      public User createUser(@RequestBody UserCreateRequestDto dto) {
      return userService.createUser(dto);
      }
    • PostMan으로 POST 요청
      {
        "name": "Daron",
        "age": 40,
        "job": "PO"
      }
    • URL에 입력 하거나 혹은 PostMan으로 GET 요청 값이 들어갔는지 확인 http://localhost:8080/users/data?id=4

주의:

  • @RequestBody 는 GET 요청에서는 사용할 수 없음.
  • Postman 같은 도구를 사용해서 테스트해야 함.

@RequestBody vs @ModelAttribute

  • Spring에서는 클라이언트가 서버로 데이터를 보낼 때 2가지 주요 방식이 있음
  1. Query Parameter (@ModelAttribute) → URL에 ?key=value형식으로 보냄

    • @ModelAttribute → 폼 데이터 (application/x-www-form-urlencoded)
    • 사용시기 : HTML 폼(form 태그)에서 입력받은 데이터를 처리할 때 사용
      → 예: 웹 페이지에서 사용자가 입력한 데이터를 서버로 보낼 때
  2. JSON Body (@RequestBody) → HTTP 요청의 Body에 JSON 형식으로 보냄

    • @RequestBody → JSON 데이터 (application/json)
    • 사용시기 : JSON 데이터를 REST API에서 처리할 때 사용
      → 예: 프론트엔드(Vue, React 등)에서 서버로 JSON 데이터를 보낼 때
  • @RequestBodyPOST 같은 요청에서만 사용할 수 있음.
    • GET 요청에서는 JSON Body를 전달할 수 없음.
    • POST, PUT, PATCH에서만 사용 가능.
  • GET 요청에서는 Query Parameter (@ModelAttribute)를 사용해야 함.
  • Postman이나 cURL 같은 도구를 사용해야 한다.
    • POST 요청을 테스트할 때는 브라우저에서 직접 실행할 수 없음.
    • 브라우저 주소창은 GET 요청만 지원하므로, JSON 데이터를 보낼 수 없음.

GET 요청을 보낼 땐 @ModelAttribute를 사용하고,
POST 요청을 보낼 땐 @RequestBody를 사용해야 한다!


1. @ModelAttribute 방식 (Query Parameter 사용)

  • URL의 Query Parameter로 데이터를 보낼 수 있음.

  • 예제:

    curl -X POST "http://localhost:8080/users" \
       -H "Content-Type: application/x-www-form-urlencoded" \
       -d "name=Daron&age=40&job=PO"
  • @ModelAttribute를 사용하면 Spring이 자동으로 객체(UserCreateRequestDto)에 값 매핑

  • 하지만 단점:

    • 데이터를 URL에 노출해야 함.
    • 복잡한 데이터를 다루기 어려움.
    • HTTP GET 요청에서도 사용 가능.

2. @RequestBody 방식 (JSON Body 사용)

  • URL이 아니라, HTTP 요청 Body에 JSON 형식으로 데이터를 보냄

  • 예제:

    curl -X POST "http://localhost:8080/users" \
       -H "Content-Type: application/json" \
       -d '{"name": "Daron", "age": 40, "job": "PO", "specialty": "App"}'
  • @RequestBody를 사용하면 Spring이 JSON을 객체 UserCreateRequestDto)로 변환해줌

  • 장점:

    • 데이터가 URL에 노출되지 않음 (보안상 유리)
    • 복잡한 데이터 구조 (예: List, Map)도 쉽게 전달 가능
    • 단점:
      • 반드시 POST, PUT, PATCH 요청에서만 사용 가능(GET은 지원 안됨)

5. 유효성 검증 (@Valid, @Validated)

  • 클라이언트가 잘못된 값을 보냈을 때 걸러내는 용도.
  • @PathVariable / @RequestParam / @RequestBody 에 대한 값 유효성 검증
    • @PathVariable: URL 경로 변수 (예: /users/{id})
    • @RequestParam: 쿼리 스트링 (예: /search?keyword=spring)
    • @RequestBody: JSON 형식의 요청 본문 (예: { "name": "John", "age": 25 })
  • @Valid자바 JSR(Java Specification Request) 표준 스펙 상 검증 어노테이션
  • @ValidatedSpring 프레임워크 자체 제공 검증 어노테이션
@PostMapping("/users")
public User createUser(@Valid @RequestBody UserCreateRequestDto dto) {
    return userService.createUser(dto);
}

필수 설정:

implementation 'org.springframework.boot:spring-boot-starter-validation'
  • build.gradle 에 검증 라이브러리 추가해야 함.

6. 응답 데이터 설정 (@JsonInclude)

  • JsonInclude 를 통해 반환하려는 객체가 null 값이 JSON 응답에서 포함될지 여부를 설정.
@JsonInclude(JsonInclude.Include.NON_NULL)
public class UserResponseDto {
    private String name;
    private String job;
    private String specialty;
}

결과:

  • null 값이면 응답에서 제외됨.

7. 정리

어노테이션사용 목적예제
@PathVariableURL 경로 변수/users/{id}/users/2
@RequestParam쿼리스트링 값 받기?id=3
@ModelAttribute여러 파라미터를 객체로 변환?name=Daron&age=40
@RequestBodyJSON 요청 데이터 받기{ "name": "Daron" }
@Valid / @Validated유효성 검증@NotNull, @Min(10)
@JsonIncludeJSON 응답에서 null 제외Include.NON_NULL

0개의 댓글