스프링 Controller Method Parameter에 사용하는 Annotation 정리

강병철·2022년 10월 31일
0

공부

목록 보기
2/3

스프링 컨트롤러의 메서드 파라미터에 사용하는 어노테이션들이 항상 헷갈려서, 참고용으로 정리해보았습니다.
틀린점이 있다면 댓글로 꼭! 지적해주시면 감사하겠습니다 ☺️


@PathVariable(생략 불가)

💡 url path variable를 메서드 파라미터로 매핑해준다

products/1 와 같은 url의 경로 변수를 인자로 받는다

@GetMapping("/mapping/{userId}")
public String mappingPath(@PathVariable(“userId”) String data){
...}
  • 변수명과 파라미터 이름이 같으면(i.e. data 대신 userId로 하면) @PathVariable String userId만 입력해줘도 된다.

@RequestHeader(생략 불가)

💡 request header를 파라미터로 매핑해준다

MultiValueMap을 통해 header를 전부 받거나, 헤더의 key를 명시하여 header 하나만 가져올 수도 있다.

public String headers(@RequestHeader MultiValueMap<String, String> map, @RequestHeader(“host”) String host){...}
  • MultiValueMap : 같은 key에 대해 여러 value가 저장 될 수 있다

    • map.get(“키값”)을 하면 List가 반환된다.
  • header 하나 가져오기

    • 여기서도 key 값과 파라미터 변수명이 일치하면 (“host”) 부분은 생략가능

@RequestParam(생략 가능)

💡 query paramter를 메서드 파라미터로 매핑해준다

?name=bc&age=… 와 같은 query parameter를 메서드 인자로 받을 수 있게 해준다. HttpServletRequest를 사용하지 않고 파라미터로 입력값을 받을 수 있다.

  • 여기서 query parameter == request parameter == query string
    은 다음과 같은 요청에서 물음표 뒤에 오는 username, age 를 말한다localhost:8080/api?username=BC&age=5

  • required = true 가 기본값이므로 해당 값이 안넘어오면 400 에러가 발생한다

사용 전

public ModelAndView save(HttpServletRequest request) {
	String username = request.getParameter("username");
	...}

사용 후

public ModelAndView save(
	@RequestParam("username") String name,
	@RequestParam int age,
	@RequestParam(required = false) String gitId,
	@RequestParam(defaultValue = "guest") String id
) {..}
  • GET 요청의 쿼리 파라미터와 POST 요청의 HTML form 둘다 request parameter에 해당된다
  • key값과 파라미터 변수명이 같다면 어노테이션 자체를 생략해도 된다

@ModelAttribute(생략 가능)

💡 query parameter를 바로 객체의 필드에 매핑해준다
  • 해당 model의 attribute name은 @ModelAttribute("이름")형태로 지정해 주지 않으면 뒤에 따라 오는 인자의 클래스 이름을 따른다 (단, camelCase로 변경)
    ex: @ModelAttribute ItemSaveForm form 이면 model 이름은 “form”이 아니라 “itemSaveForm”이 된다

  • 객체의 필드에 매핑이 되기 위해서는 해당 필드들에 값을 주입해주는 생성자 또는 Setter가 있어야 한다(이때 생성자의 접근제어자가 private이어도 작동한다)

  • required 옵션의 default가 true이기 때문에, @ModelAttribute를 적용한 객체에 username이라는 필드가 있는데 request parameter로 해당 값이 넘어오지 않으면 에러가 발생하며 나머지 정상적인 값들도 매핑이 되지 않는다
    -> RequestParam이랑 헷갈렸던 것 같다. 객체의 필드값이 넘어오지 않아도 에러가 발생하지 않는다. 그저 (초기값이 지정되지 않았다면) null로 남겨질 뿐.

  • @ModelAttribute도 생략할 수 있다

    • 파라미터가 String, int, Integer 같은 단순 타입일 경우 Annotation이 없으면 @RequestParam으로 인식되고
    • 나머지 타입(ex: 내가 만든 객체)들은 @ModelAttribute으로 인식된다

@RequestBody (생략 불가)

💡 `request body`를 메서드 파라미터에 매핑해준다
  • 객체의 필드에 매핑되기 위해서는 기본생성자(인자가 없는 비어있는 생성자; 접근제어자 상관 없음)가 있어야 한다

  • 신기하게도 필드를 직접 세팅하는 Setter나 생성자가 따로 없어도 정상 작동한다

  • @ModelAttribute 과는 다르게, DTO에 username 필드가 있을 때 request body로 해당 값이 넘어오지 않아도 에러가 나지 않는다.

    • 단, required = true 가 기본값이라서, DTO의 필드 중 하나 이상의 값은 넘어와야한다. 안그러면 400 에러가 발생한다
    • required = false로 해두고 아무 값도 안 넘기면 DTO 자체가 null이 된다

0개의 댓글