스프링 controller에서 파라미터를 받는 다양한 방법 ( @RequestParam, @RequestBody, @PathVariable)

국물빌런·2020년 4월 24일
11

출처부터 남긴다
https://takeknowledge.tistory.com/39

컨트롤러에서 파라미터를 받을 수 있는 다양한 방법이 있다

1. @RequestParam 어노테이션 활용

GET방식으로 넘어온 URI의 queryString을 받기에 적절해

html부터 단계별(?)로 밟아온 사람이라면 가장 쉽게 이해할 수 있을 어노테이션이다.

예를 들어 http://localhost:8080/reservation/api/reservations?reservationEmail=test@naver.com 이런 URI가 있다고 치면
Controller 단에서

@RestController
@RequestMapping(path = "/api")
public class ReservationsApiController {
 
    // email로 예약 내역 조회
    @GetMapping(path = "/reservations")
    public Response<List<String>> getReservations(
            @RequestParam(value = "reservationEmail",required = false) String reservationEmail) {
 
        return reservationService.getReservationByEmail(reservationEmail);
    }

@RequestParam을 이렇게 쓰면 받을 수 있다.
value에는 넘어오는 파라미터의 name값을 적으면 되고
( value인데 name 값을 받는다. 근데 name 속성도 있다. 검색해보니 결국 같다고.. ㅋ 골라쓰면 되는 듯 하다)
required = false는 필수는 아니지만 @RequestParam의 required의 기본값은 true 여서
적지 않으면 선언한 파라미터가 반드시 있어야 한다. 없으면 400 에러 발생.
그리고 위 예제에는 없지만 defaultValue 속성도 있는데 이
를 활용하면 값이 없을 경우 파라미터에 매핑될 기본 값을 세팅해 줄 수도 있다.

2. @PathVariable 활용

이 어노테이션을 활용하면
http://localhost:8080/reservation/api/reservations/2 와 같이 좀 더 깔끔한 URI를 만들 수 있다.
(뒤에 붙은 2가 파라미터!)

사용법은 간단하다

@RestController
@RequestMapping(path = "/api")
public class ReservationsApiController {
 
    // 예약 취소
    @PutMapping(path = "/reservations/{reservationId}")
    public Reservations cancleReservations(@PathVariable(name = "reservationId") Integer reservationInfoId) {
 
        return reservationService.cancelReservationById(reservationInfoId);
    }

Mapping하는 Path에 (꼭 PutMapping 이어야 할 필요는 없습니다다. 써야 해서 쓴 거지 GetMapping이어도 됩니다~)
{}를 활용해 변수처럼 적어준 뒤 @PathVariable 어노테이션 뒤에 {} 안에 적은 변수 명을 name 속성의 값으로 넣는다.
그 후 이를 받을 자료형과 변수명을 옆에 선언해주면 잘 작동한다.
rest api에서 많이 쓰인다.

3 @RequestBody 활용

http요청의 body 부분을 java 객체로 받을 수 있게 해주는 어노테이션. 주로 json을 받을 때 활용한다.
뭔가 어려워 보이지만 어렵지 않다 예제를 보자.
예를 들어

{
  "displayInfoId": 1,
  "prices": [
    {
      "count": 5,
      "productPriceId": 1,
      "reservationInfoId": 0,
      "reservationInfoPriceId": 0
    },
        {
      "count": 3,
      "productPriceId": 2,
      "reservationInfoId": 0,
      "reservationInfoPriceId": 0
    }
  ],
  "productId": 1,
  "reservationEmail": "test@naver.com",
  "reservationName": "API테스트",
  "reservationTelephone": "010-1234-1234",
  "reservationYearMonthDay": "2019.09.01"
}

이런 json 데이터를 서버로 넘긴다고 하면
getter setter는 생략한다. 실제로는 구현해야 함

역시 getter setter 생략. 실제로는 구현해야 함
이렇게 json 데이터를 담은 java 객체를 구현하고

해당 요청을 매핑하는 컨트롤러 메소드에서

@RestController
@RequestMapping(path = "/api")
public class ReservationsApiController {
 
    // 예약하기
    @PostMapping(path = "/reservations")
    public Reservations setReservations(@RequestBody ReservationParam reservationParam) {
 
        return reservationService.setReservation(reservationParam);
 
    }

이렇게 @RequestBody 어노테이션을 선언하고 생성한 java 객체를 파라미터를 담을 변수로 적어주면
json 데이터로 날아온 파라미터가 고스란히 java객체에 담긴다. 매우 편리한 어노테이션!

4 @MAP 활용

JSON 데이터를 받는데 데이터마다 DTO를 만들기도 귀찮고 DTO를 만들만큼 복잡하지 않고 단순히 string으로 key:value형태라면 굳이 DTO를 만들지 않고 MAP으로 간단히 받을 수 있다.

데이터가 아래와 같은 경우

{
  "Id": "soup",
  "password" : "billein"
  "email" : "shson@velog.io"
}
@RestController
@RequestMapping(path = "/api")
public class ReservationsApiController {
 
    // 예약하기
    @PostMapping(path = "/reservations")
    public Reservations setReservations(@RequestBody Map<String,String> param) {
 
 		String id = param.get("id");
 		String pwd = param.get("password");
 		String email = param.get("email");
        return reservationService.setInfo(id,pwd,email);
 
    }
profile
국물을 달라

3개의 댓글

comment-user-thumbnail
2021년 5월 2일

정말 도움이 많이 되었습니다.

답글 달기
comment-user-thumbnail
2021년 11월 9일

문제 해결에 큰 도움이 됐습니다. 감사합니다.

답글 달기
comment-user-thumbnail
2022년 12월 27일

도움 많이 되었습니다 감사합니다^^

답글 달기