[Spring 3.1] 스프링 MVC 애너테이션
@RequestMapping
스프링 MVC는 핸들러 매핑으로 메서드를 연결해준다.
// 슬래시로 끝나지 않으면 hello.* hello/ 도 함께 매핑됨
@RequestMapping("/hello")
public String hello() { ... }
// @GetMapping을 이런식으로 구현
@RequestMapping(value = "/hello" method = RequestMethod.GET)
public String hello() { ... }
// 매핑에 요청 파라미터 지정 가능
@RequestMapping(value = "/hello" params="type=admin")
public String hello() { ... }
@RequestMapping(value = "/hello" params="!type")
public String hello() { ... }
// HTTP 헤더로도 구분 가능
@RequestMapping(value = "/hello" headers="content-type=text/*")
public String hello() { ... }
// 리턴 타입이 void인 경우 비어있는 모델과 뷰를 반환한다.
@RequestMapping(value = "/hello" headers="content-type=text/*")
public void hello() { ... }
/**
* 클래스에서 공통 설정을, 메서드에서 세부 설정을 진행함
* 중복 시 더 세부적인게 선택됨
*/
@RequestMapping과 상속이 결합돼도 직관적으로 적용된다.
제네릭스, @RequestMapping, 상속을 적절하게 사용해 유지 보수 편하고 간결한 코드를 작성하자.
디스패처 서블릿은 HttpServletRequest와 HttpServletResponse를 받아서 컨트롤러가 사용하는 타입으로 변환해서 제공한다.
그리고 컨트롤러는 작업을 처리하고 결과를 ModelAndView에 담아 디스패처 서블릿에게 돌려준다.
핸들러 어댑터는 데이터를 넘기는 작업만 수행한다. (핸들러 어댑터가 데이터를 가공하지 않는다)
스프링 3.0에서는 @Controller 애너테이션을 통해 컨트롤러 역할을 담당하는 메서드의 파라마터 관련 정보와 반환 타입 등을 지정해서 유연하게 사용할 수 있고, 때문에 핸들러 어댑터가 복잡해졌다.
애너테이션 기반 컨트롤러는 기존에 사용하던 컨트롤러 방식을 완벽하게 대체하고 훨씬 더 편리하게 사용할 수 있다.
@RequestMapping("/hello")
public String hello(@Requestparam("name") String name, @CookieValue("auth") String auth, Model model) {
...
}
@RequestParam 애너테이션으로 HTTP 요청의 name 파라미터를 추출해 파라미터에 전달한다.
@CookieValue 애너테이션으로 요청정보의 쿠기 값 중 auth에 해당하는 값을 파라미터에 전달한다.
스프링은 @RequestMapping으로 매핑된 메서드의 파라미터와 리턴 값을 통해 적절하게 값을 준비해서 호출한다.
아래는 메서드의 파라미터로 사용될 수 있는 종류이다.
HttpServletRequest, HttpServletResponse
대부분 HttpServlet을 가공한 데이터를 활용하겠지만, 그 자체 오브젝트가 필요한 경우가 있다.
HttpServlet을 오브젝트로 직접 다루는 기능을 제공한다.
HttpSession
위에서 언급한 HttpServletRequest를 통해서 HttpSession을 찾아 올 수 있지만, HttpSession을 사용하면 바로 가져올 수 있다.
멀티스레드 관련 이슈가 있으니 주의하자.
WebRequest, NativeWebRequest
서블릿 API에 종속적이지 않으면서 요청정보를 가지고 있는 객체이다.
보통 서블릿을 쓰니.. 잘 사용하지는 않는다.
Locale
디스패처 서블릿의 지역정보 리졸버가 결정한 Locale 오브젝트이다.
@PathVariable
쿼리스트링 대신 URL 경로로 풀어서 사용할 수 있다.
게시글을 조회하거나 회원을 조회할 때 user/10 . post/11 이런 식으로 URL을 깔끔하게 가져갈 수 있다.
@RequestMapping("/user/{id}/post/{pid}")
public String hello(@PathVariable("id") int id, @PathVariable("pid") int pid) { ... }
한 번에 사용할 수 있고, 타입 변환에 주의해야 한다.
@RequestParam
HTTP 요청 파라미터를 넣어준다.
@RequestMapping("/hello")
public String hello(@RequestParam("name") String name, @RequestParam("id") int id) { ... }
@RequestMapping("/hello")
public String hello(@RequestParam Map<String, String> params) { ... }
@RequestMapping("/hello")
public String hello(@RequestParam int id) { ... }
특정 값만 받아올 수 있고, Map으로 모든 값을 받아올 수 있다.
메서드 파라미터 이름과 요청 파라미터 이름이 같은 경우 생략할 수 있고, 기본값도 설정할 수 있다.
@CookieValue
HTTP와 전달된 쿠키 값을 메서드 파라미터에 넣는다.
public String hello(@CookieValue(value="auth", required=false, defaultValue="dd" S tring auth){ ... }
@RequestParam 처럼 쿠키 값이 반드시 존재해야 사용할 수 있다. 예외를 피하려면 역시 required를 false로 설정하고 디폴트를 설정해 줘야 한다.
@RequestHeader
요청 헤더 정보를 넣어준다.
public void hello(@RequestHeader("Keep-Alive") long keepAlive) { ... }
역시 기본값과 사용 여부를 지정할 수 있다.
@ModelAttribute
파라미터와 메서드에 모두 부여할 수 있다.
모델로 사용되는 오브젝트지만 RequestParam 은 파라미터 값을 1:1로 받을 때 주로 사용하고 ModelAttribute는 도메인 오브젝트나 DTO에 바인딩해서 한 번에 받을 때 사용한다.
폼 데이터를 받을 때 RequestParam 대신 ModelAttribute로 받는게 더 효율적이다.
역시 RequestParam 처럼 생략할 수 있다.
스프링은 단순 타입이 파라미터에 있는 경우 RequestParam을, 복잡한 객체가 파라미터에 있는 경우 ModelAttribute가 생략됐다고 간주한다.
모호함을 피하려면 생략하지 않는 것도 좋다.
이 외에도 ModelAttribute는 기본적으로 반환되는 모델에 해당 값을 추가해준다.
Errors, BindingResult
@ModelAttribute가 붙은 파라미터는 검증 작업이 추가적으로 진행된다.
ModelAttribute는 요청 파라미터에서 타입 변환 문제가 발생했을 때 에러로 처리하는 대신 BindException 타입의 오브젝트에 담아 컨트롤러로 전달한다.
사용자의 입력 값에 오류가 있는 경우 적절한 에러 페이지나 에러 메세지를 통해 사용자가 입력값을 수정할 기회를 준다
@RequestMapping("/hello")
public String hello(@ModelAttribute User user, BindingResult bindingResult) { ... }
BindingResult 객체에는 파라미터를 바인딩하다가 발생한 변환 오류 등이 저장된다.
해당 객체에 오류가 없다면 DB에 등록하고, 오류가 담겨 있다면 사용자가 폼을 수정하도록 한다.
BindingResult나 Error는 ModelAttribute 바로 뒤에 위치해야 한다.
@RequestBody
해당 애너테이션이 붙은 파라미터에는 HTTP 요청의 본문이 전달된다.
xml이나 json기반으로 데이터를 요청할 때 자주 사용된다.
@ResponseBody 가 메서드 레벨에 부여되면 메서드는 메세지 컨버터를 통해 HTTP 응답 메세지의 본문으로 반환값을 설정한다.
HttpMessageConverter는 HTTP 요청 본문을 객체로, 객체를 HTTP 응답 본문으로 변환할 때 사용된다.
@RequestBody와 @ResponseBody 애너테이션이 붙어 있는 경우에만 메세지 컨버터가 작동한다고 생각하면 된다.
요점은 뷰를 해석할 때는 ViewResolver와 View 구현체가 사용되고, 메세지 컨버터는 @RequestBody @ResponseBody 애너테이션이 붙었을 때 사용되며 HTTP 응답을 직접 만드는 부분이다.
덧붙이자면...
BufferedReader는 가변길이의 문자를 받을 수 있다.
즉, Buffer는 ByteStream 통신 시 가변길이를 다룰 수 있도록 도와주기도 한다.
따라서 고정된 길이를 다룰 때 보다 데이터를 효과적으로 다룰 수 있고 (고정 길이는 10인데 2만큼만 쓰면 8만큼의 손실이 있다) @ResponseBody를 쓰면 BufferedWriter가 동작하고 @RequestBody를 쓰면 BufferedReader가 동작한다.
utf-8 인코딩 방식은 하나의 문자를 인코딩 할 때 최소 8비트를 사용하는 방식이다.
최소 8비트를 사용하고 중국어 같은 경우는 3바이트를 사용한 한 문자를 표현하는 등 한 문자를 표현하는데 최대 32비트를 쓸 수 있다.
8비트는 1바이트이고, 바이트는 통신의 기본 단위로 사용돼 ByteStream을 통해 데이터를 주고받는다.
자바에서는 InputStreamReader 객체를 사용하는데, 해당 객체는 배열로 데이터를 다뤄 크기가 정해져 있다.
단점을 극복하기 위해 가변길이의 문자를 다룰 수 있는 BufferedReader가 도입됐다.
@Value
환경 변수 값을 가져올 때 사용한다.
컨트롤러의 리턴 타입은 디스패처 서블릿에게 돌려줄 때는 모델과 뷰로 변환된다.
이후 모델과 뷰는 디스패처 서블릿이 적절하게 변환해 클라이언트에게 돌려준다.
'Spring > Spring 3.1' 카테고리의 다른 글
[Spring 3.1] 스프링 MVC와 웹 기술 - 핸들러 (0) | 2023.05.13 |
---|---|
[Spring 3.1] 데이터 엑세스 기술 (0) | 2023.05.11 |
[Spring 3.1] IoC 컨테이너와 스프링의 동작 원리 (0) | 2023.05.10 |
[Spring 3.1] Annotation (0) | 2023.05.04 |
[Spring 3.1] Aspect Oriented Programming (0) | 2023.04.28 |
댓글
이 글 공유하기
다른 글
-
[Spring 3.1] 스프링 MVC와 웹 기술 - 핸들러
[Spring 3.1] 스프링 MVC와 웹 기술 - 핸들러
2023.05.13 -
[Spring 3.1] 데이터 엑세스 기술
[Spring 3.1] 데이터 엑세스 기술
2023.05.11 -
[Spring 3.1] IoC 컨테이너와 스프링의 동작 원리
[Spring 3.1] IoC 컨테이너와 스프링의 동작 원리
2023.05.10 -
[Spring 3.1] Annotation
[Spring 3.1] Annotation
2023.05.04