Post

(Spring) Controller에서 사용하는 애너테이션

@ModelAttribute / @RequestBody 애너테이션은 웬만하면 붙여주는 편이 명확하다.

  • @ModelAttribute를 명시하지 않아도 자동으로 URL 파라미터를 객체로 매핑해주고, GET은 관례적으로 URL 파라미터로 데이터를 전달하기 때문에, 굳이 @ModelAttribute를 사용해야 하느냐 라고 생각할 수 있는데
  • Controller에서 GetMapping 메서드는 사실 (URL 파라미터/HTTP 바디) 양 쪽 모두 데이터를 받을 수 있다.

  • 따라서 항상 @ModelAttribute / @RequestBody를 명시해 주는 편이 좋다.

@RequestParam

queryString이나 form 요청에서 파라미터를 하나 하나 받을 때 사용한다.

1
2
3
4
5
6
7
8
9
@RequestParam("name")

@RequestParam(value="name", defaultValue="unknown")


// ?name이 없어도 4\*\* 뜨지 않음

@RequestParam(value="name", required=false)

  • 파라미터 하나 하나 마다 애너테이션을 적어줘야 하니 여러개를 받을 때는 지저분해져서 부적합하다.
    • 여러개를 한번에 받기 위해 아래 처럼 Map으로 받는 방식은 쓰지 않는 것이 좋다.
    • 대신 커맨드 객체(+@ModelAttribute)를 사용하자.
1
2
3
// 아래 방식은 별로다. 커맨드 객체를 쓰자
@RequestParam HashMap<string,string> paramMap

@RequestParam VS @PathVariable

자원 자체를 나타낼 때는 @PathVariable orderBy나, filter 같은 조건을 명시하는 것에는 @RequestParam 근데 깔끔하게 설계가 잘 안되는 경우도 있으니까. 상황에 따라 맞춰서 사용하는 경우도 있음. 포함 관계가 아닐 때가 애매한데, 이는 검색 조건으로 보고 @RequestParam으로 처리하는 것이 매끄러운 것 같기도 함.

REST api / RESTful 이란.

@RequestParam이나 @PathVariable이나 파라미터가 너무 많은 경우 Map이나 command 객체 사용 가능

@ModelAttribute

1
2
3
4
public List<User> getUserList(@ModelAttribute UserSearch userSearch) {
   return userService.getUserList(userSearch);
   }

  • URL 파라미터 또는 POST Form Data 형태의 파라미터를 UserSearch 클래스의 필드들로 매핑해준다.
    • 이렇게 자동으로 매핑되어 반환되는 객체를

    커맨드 객체 라고 부른다.

  • 매핑 rule? ( 여기서 constructor는 @ConstructorProperties와 무관 )
    • NoArgsConstructor & AllArgsConstructor 둘 다 있는 경우
      • NoArgsConstructor 호출
      • setter 호출해서 param 초기화
    • AllArgsConstructor만 있는 경우
      • AllArgsConstructor 호출해서 param 초기화
      • setter 호출해서 param 초기화 (덮어써짐)
    • 즉, constructor에도 없고 setter도 없는 필드는 초기화되지 않는다.
  • Spring 5.2.4 기준 위와 같이 동작한다.
  • Spring 4.3.4 기준 반드시NoArgsConstructor와 Setter가 존재해야만 한다. (No default constructor found;라고 에러 발생.)
    • 이런 관점에서도 presentationdto를 반드시 도메인 모델과 분리하는 것이 좋다. *** @ModelAttribute("query")와 같이 쓰면 jsp에서 query로 데이터에 접근하도록 지정할 수 있음.

@RequestBody

  • 바디를 통해 받은json 형태의 데이터 를, jackson ObjectMapper 사용해서 바로 객체로 매핑해준다.
    • json 형태의 데이터를 받는 용도이기 때문에, form 요청 (application/x-www-form-urlencoded 형태)은 받을 수 없다.
    • content-type이 form인데 @RequestBody로 받는 경우 415 Unsupported Media Type 발생
  • 매핑 룰은 여기에[Java] Jackson Serialization

@Valid와 Errors

@Valid를 사용할 때, Errors errors를 파라미터로 받으면 어떤 항목에서 에러가 발생했는지 메서드 내에서 처리할 수 있다. Valid는 ModelAttribute, RequestBody 모두 동작한다.

DTO 생성 시점에 validation

별도 annotation 도움 없이 생성자나 init block 활용한다.

@RequestAttribute and @SessionAttribute Annotations

https://www.baeldung.com/whats-new-in-spring-4-3#SessionAttribute

기타 Controller와 관련된 애너테이션

This post is licensed under CC BY 4.0 by the author.