-
Controller에 인자값은 어떤값이 올 수 있을까?프로젝트/게시판 프로젝트 2022. 5. 6. 00:01728x90
Controller가 매우 다양한 인자 값을 받아올 수 있기 때문에 어떤 값들을 받아 올 수 있는지 어떻게 받아오는 게 적절할지 조사해보고자 합니다.
Spring Controller에서 Parameter를 받는 방식
HttpServletRequest를 통해 받는 방법
@RequestMapping("/test") public String test(HttpServletRequest req) { String userId = req.getParameter("userId"); String password = req.getParameter("password"); return "test"; }
getParameter()는 String값을 반환합니다.
이때 parameter로 보낸 변수명과 getParameter("변수명")에 들어갈 변수명이 일치해야 합니다.
@RequestParam을 통해 직접 매칭 하는 방법
1개의 HTTP 요청 파라미터를 받기 위해 사용합니다.
localhost:8080? id=myId 같은 URL을 받을 수 있습니다.
@RequestMapping("/test") public String test(@RequestParam(value="id", defaultValue="기본값") String id) { System.out.prinln(id); return "test"; }
여기에 추가적으로 required라는 파라미터를 설정할 수 있는데 기본값이 true이며 해당 파라미터를 사용하지 않고 요청을 보내게 되면 HTTP 400 에러를 받게 됩니다.
value는 파라미터의 이름을 명시하는것이며, defaultValue는 해당 파라미터의 기본값을 명시합니다.
위의 방법은 복잡하기 때문에 다음과 같이 축약하여 사용할 수 있습니다.
@RequestMapping("/test") public String test(@RequestParam String id) { System.out.prinln(id); return "test"; }
@ModelAttribute를 통해 Object로 받기
RequestParam과 비슷한데 1:1로 파라미터를 받을 경우에는 @RequestParam, 도메인이나 오브젝트를 받을 경우에는 @ModelAttribute를 활용합니다.
또한 각 파라미터마다 valid 옵션을 줄 수 있어 Null 체크 등의 검증작업을 수행할 수 있습니다.
@PostMapping("/test") public String test(@ModelAttribute("user") UserVO user) { System.out.prinln(user.getId()); return "test"; }
@RequestBody를 통해 Object로 받는 방법
클라이언트가 전송하는 HTTP Body 내용을 Java Object로 변환시켜주는 역할을 사용합니다.
Body가 존재하지 않는 HTTP Get 메서드에 @RequestBody를 활용하려고 한다면 에러가 발생합니다.
내부적으로 Reflection을 사용해 값을 할당하기 때문에 @RequestBody에는 값을 주입하기 위한 생성자나 Setter가 필요 없습니다.
@PostMapping("/test") public String test(@RequestBody UserVO user) { System.out.prinln(user.getId()); return "test"; }
JSON이나 XML같은 데이터를 읽을 때 사용합니다.
@PathVariable로 받는 방법
@RequestMapping(value="/test/{email}", method=RequestMethod.GET) public String test(@PathVariable("email") String email) { return "test"; }
@RequestMappind에 보이는 {email}이라는 부분에 @PathVariable이 매핑됩니다.
{email} 부분을 변수로 활용하여 Service에서 활용할 수 있습니다. (해당 email관련 CRUD 등등)
@RequestParam , @ModelAttribute @RequestBody 차이점
@RequestParam
- 1:1로 값을 바인딩
- 잘못된 값이 들어오면 400 BadRequest 발생
@ModelAttribute
-도메인이나 오브젝트를 바인딩할 수 있습니다.
-setter를 사용하여 담아주기 때문에 해당 매개변수의 바인딩받는 필드에는 setter가 있어야 합니다.
-잘못된 값이 들어와도 작업은 계속됩니다( WebExchangeBindException 발생)
@RequestBody
- Post 요청시 기본 생성자가 있어야 하며 Setter는 없어도 됩니다.
- Get 요청시에는 Setter가 존재해야 합니다.
이유
POST 요청시 JSON으로 데이터가 넘어오고 Jackson2 HttpMessageConverter의 ObjectMapper를 사용하여 Setter가 없어도 값이 할당됩니다.
하지만 GET요청시에는 Query Parameter가 넘어오게 되고 Spring에서는 WebDataBinder를 사용합니다.
별다른 설정이 없다면 기본 값 할당 방법인 Java Bean방식을 사용하여 setter가 없으면 동작하지 않습니다.
이때 setter가 아닌 field에 직접 접근하기 위해서 initDirectFieldAccess를 사용하면 됩니다.
다음과 같이 ControllerAdvice에 선언하면 GET 요청 시에도 setter가 없어도 값이 잘 할당됩니다.
@Slf4j @ControllerAdvice public class WebControllerAdvice { @InitBinder public void initBinder(WebDataBinder binder) { binder.initDirectFieldAccess(); } }
자세한 사항을 보고 싶다면 여기를 참고하세요.
출처
https://jesus-never-fail.tistory.com/25
https://goateedev.tistory.com/284
https://parkadd.tistory.com/70
https://mangkyu.tistory.com/72
https://jojoldu.tistory.com/407
'프로젝트 > 게시판 프로젝트' 카테고리의 다른 글
테스트코드에서는 H2 DB를 사용하자! (0) 2022.05.11 Spring Rest API 예외처리 (feat. 스프링의 기본적인 예외 처리 방법과 Best Practice) (0) 2022.05.10 RestController에서 클라이언트에게 어떤 값을 반환해야 할까? (0) 2022.05.05 Entity와 DTO를 분리하자! (0) 2022.05.04 @Builder 제대로 알고 사용해보기 (0) 2022.04.30