티스토리 뷰

728x90

스프링 웹 MVC(inflearn) - 백기선

SpringMVC 활용

  • 핸들러 메소드 아규먼트 : 주로 요청 그 자체 또는 요청에 들어있는 정보를 받아오는데 사용
    핸들러 메소드 아규먼트 설명
    WebRequest
    NativeWebRequest
    ServletRequest(Response)
    HttpServletRequest(Response)
    요청 또는 응답 자체에 접근이 가능한 API
    InputStream
    Reader
    OutputStream
    Writer
    요청본문 (body)를 읽어오거나, 응답 본문을 쓸때 사용할 수 있는 API
    PushBuilder 스프링5에 생김.
    HTTP/2 리소스 푸쉬에 사용
    (브라우저에 필요한 이미지를 새로 요청하지 않고 서버에서 능동적으로 이미지를 푸쉬)
    HttpMethod GET, POST ... 등에 대한 정보
    Locale
    TimeZone
    ZoneId
    LocaleResolver가 분석한 요청의 Locale
    @PathVariable URI 템플릿 변수 읽을 때 사용
    @MatrixVariable URI 경로 중에 키/값 쌍을 읽어 올 때 사용
    @RequestParam 서블릿 요청 매개변수 값을 선언한 메소드 아규먼트 타입으로 변환해준다.
    단순 타입인 경우에 이 애노테이션을 생략할 수 있다.
    @RequestHeader 요청 헤더 값을 선언한 메소드 아규먼트 타입으로 변환해준다.
    ...  
  • 핸들러 메소드 리턴 : 주로 응답 또는모델을 랜더링할 뷰에 대한 정보를 제공하는데 사용
    핸들러 메소드 리턴 설명
    @ResponseBody 리턴 값을 HttpMessageConverter를 사용해 응답 본문으로 사용한다.
    HttpEntity
    ResponseEntity
    응답 본문 뿐 아니라 헤더 정보까지, 전체 응답을 만들 때 사용한다.
    String ViewResolver를 사용해서 뷰를 찾을 때, 사용할 뷰 이름.
    View 암묵적인 모델 정보를 랜더링할 뷰 인스턴스
    Map
    Model
    (RequestToViewNameTranslator를 통해서) 암묵적으로 판단한 뷰 랜더링할 때 사용할 모델 정보
    @ModelAttribute (RequestToViewNameTranslator를 통해서) 암묵적으로 판단한 뷰 랜더링할 때 사용할 모델 정보에 추가한다. 이 애노테이션은 생략할 수 있다.

핸들러 메소드 : URI 패턴

  • @PathVariable
    • 요청 URI 패턴의 일부를 핸들러 메소드 아규먼트로 받는 방법
    • 타입 변환 지원
    • (기본)값이 반드시 있어야 한다.
    • Optional 지원
  • @MatrixVariable
    • 요청 URI 패턴에서 키/값 쌍의 데이터를 메소드 아규먼트로 받는 방법
      • ex) GET /events/1;name=keesun
      • ex) GET /events/id/1/name/keesun
    • 타입변환 지원
    • (기본)값이 반드시 있어야 한다.
    • Optional 지원
    • 기본적으로 비활성화, 활성화를 위해서는 설정이 필요하다.
    • @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void configurePathMatch(PathMatchConfigurer configurer) { UrlPathHelper urlPathHelper = new UrlPathHelper(); urlPathHelper.setRemoveSemicolonContent(false); configurer.setUrlPathHelper(urlPathHelper); } }

참고


핸들러 메소드 : 요청 매개변수(단순 타입)

  • 요청 매개변수
    • form 데이터
    • query parameter
  • @RequestParam
    • 요청 매개변수에 들어있는 단순 타입 데이터를 메소드 아규먼트로 받아올 수 있다.
    • 값이 반드시 있어야 한다.
      • required=false 또는 Optional을 사용해서 부가적인 값으로 설정할 수 도 있다.
    • String이 아닌 값들은 Conversion을 지원한다.
    • Map<String, String> 또는 MultiValueMap<String, String> 을 사용해서 모든 요청 매개변수를 받아 올 수도 있다.
    • 이 애노테이션은 생략할 수 있다.

참고


핸들러 메소드 : 폼 서브밋

  • form을 보여줄 요청 처리
    • GET /events/form
    • 뷰 : events/form.html
    • 모델 : "event", new Event()
  • 타임리프
    • @{}: URL 표현식
    • ${}: variable 표현식
    • *{}: selection 표현식

참고


핸들러 메소드 : @ModelAttribute

  • @ModelAttribute
    • 여러 곳에 있는 단순 타입 데이터를 복합 타입 객체로 받아오거나, 해당 객체를 새로 만들 때 사용할 수 있다.
    • 여러곳에서 오는 정보들로 객체를 바인딩 해준다.
      • URI 패스, 요청매개변수, 세션 등
      • 잘못된 타입이 들어오게 되면 BindingException 400 에러가 발생한다.
        • @ModelAttribute 바로 오른쪽에 BindingResult 타입의 아규먼트를 받으면 Exception을 BindingResult에 담고 요청은 통과가 된다. (BingdingResult의 상위객체인 Errors로도 가능하다.)
        • public Event getEvent(@Valid @ModelAttribute Event event, BingdingResult bindingResult) { if (bindingResult.hasErrors()) { bingdingResult.getAllErrors().forEach(e -> { System.out.println(e.toString()); }); } return event; }
      • 바인딩 이후 검증 작업을 추가하고 싶은 경우 @Valid 또는 @Validated 어노테이션을 사용할 수 있다.
        • @Validated 그룹 validation, Spring 제공
        • validation에 대한 에러도 BindingResult에 담아준다.
    • 생략이 가능하다.

핸들러 메소드 : @Validated

  • 스프링 MVC 핸들러 메소드 아규먼트에 사용할 수 있으며, validation group이라는 힌트를 사용할 수 있다.
  • @Valid 는 그룹을 지정할 방법이 없다.
  • @Validated 는 스프링이 제공하는 어노테이션으로 그룹 클래스를 설정할 수 있다.
  • 기존 @Valid 기능을 포함 (똑같이 사용)
  • 추가로 그룹 지정
    • Controller
    • public Event getEvent(@Validated(Event.ValidateLimit.class) @ModelAttribute Event event, BingdingResult bindingResult) { if (bindingResult.hasErrors()) { bingdingResult.getAllErrors().forEach(e -> { System.out.println(e.toString()); }); } return event; }
  • public class Event { interface ValidateName {} interface ValidateLImit {} @NotBlank(groups = ValidateName.class) private String name; @Min(value = 0, groups = ValidateLimit.class) private Integer limit; }

핸들러 메소드 : 폼 서브밋 (에러처리)


핸들러 메소드 : @SessionAttributes

  • 모델 정보를 HTTP 세션에 저장해주는 어노테이션
    • HttpSession을 직접 사용할 수 도 있지만, 이 어노테이션에 설정한 이름에 해당하는 모델 정보를 자동으로 세션에 넣어준다.
    • @ModelAttribute 는 세션에 있는 데이터도 바인딩한다.
    • 여러화면에서 사용하는 객체를 공유해야하는 경우 사용한다.
  • @SessionAttributes("event") @Controller public class EventController { @GetMapping("/events/form") public Event getEvent(Model model) { Event newEvent = new Event(); newEvent.setLimit(50); model.addAttribute("event", newEvent); return "events/form"; } }
  • SessionStatus를 사용해서 세션 처리 완료를 알려줄 수 있다.
    • 폼 처리 끝나고 세션을 비울 때, 사용한다.
    • @SessionAttributes("event") @Controller public class EventController { public String getEvent(@Valid @ModelAttribute Event event, SessionStatus sessionStatus) { sessionStatus.setComplete(); return "redirect:/events/list"; } }

핸들러 메소드 : 멀티 폼 서브밋

  • 세션을 사용해서 여러 폼에 걸쳐 데이터를 나눠 입력 받고 저장하기
    • 이벤트 이름 입력받고
    • 이벤트 제한 인원 입력받고
    • 서브밋 -> 이벤트 목록으로
  • 완려된 경우 세션에서 모델 객체 제거
    • SessionStatus

핸들러메소드 : SessionAttribute

  • HttpSession에 들어있는 값을 참조할 때 사용
    • HttpSession을 사용할 때 보다 타입 컨버젼을 자동으로 지원
    • HttpSession에 데이터를 넣고 빼고 싶은 경우에는 HttpSession을 사용할 것.
  • @SessionAttributes 와는 다르다.
    • @SessionAttributes 는 해당 컨트롤러 내에서만 동작한다.
    • @SessionAttribute 는 컨트롤러 밖(인터셉터 또는 필터 등)에서 만들어 준 세션에 접근할 때, 사용한다.

핸들러 메소드 : RedirectAttributes

  • 리다이렉트 할 때 기본적으로 Model에 들어있는 원시타입 데이터는 URI query parameter에 추가된다.
    • 스프링 부트에서는 이 기능이 기본적으로 비활성화 되어 있다.
      • ignore-default-model-on-redirect 프로퍼티를 사용해서 활성화 할 수 있다.
  • 원하는 값만 리다이렉트 할 때, 전달하고 싶다면 RedirectAttributes에 명시적으로 추가 할 수 있다.
  • 리다이렉트 요청을 처리하는곳에서 query paramerter를 @RequestParam 또는 @ModelAttributes로 받을 수 있다.
    • ex ) GET /events/list?name=aaaa 으로 리다이렉트 됨.
  • @GetMapping("/events/form-limit") public String getEvent(@Valid @ModelAttribute Event event, SessionStatus sessionStatus, RedirectAttributes attributes) { sessionStatus.setComplete(); attributes.addAttribute("name", event.getName()); return "redirect:/events/list"; }

핸들러 메소드 : Flash Attributes

  • 주로 리다이렉트 시, 데이터를 전달할 때 사용한다.
    • 데이터가 URI에 노출되지 않는다.
    • 임의의 객체를 저장할 수 있다.
    • 보통 HTTP 세션을 사용한다.
      • 리다이렉트 하기전에 데이터를 HTTP 세션에 저장하고 리다이렉트 요청을 처리한 다음 그 즉시 제거한다. (1회성)
@GetMapping("/events/form-limit")public String getEvent(@Valid @ModelAttribute Event event, SessionStatus sessionStatus, RedirectAttributes attributes) {  sessionStatus.setComplete();  attributes.addFlashAttribute("event", event);  return "redirect:/events/list";}

핸들러 메소드 : MultipartFile

  • 파일 업로드 시, 사용하는 메소드 아규먼트
  • MultipartResolver 빈이 설정 되어야 사용할 수 있다.
    • 빈이 없는 경우 DispatcherServelet 에서 설정하지 않는다.
    • 즉, 빈이 없는경우 MultipartResolver를 사용하지 않는다.
    • 스프링 부트를 사용하는 경우 MultipartResolver 빈의 등록을 자동설정이 해준다.
      • 파일 업로드 관련 스프링 부트 설정
        • MultipartAutoConfiguration
        • MultipartProperties
    • POST multipart/form-data 요청에 들어있는 파일을 참조할 수 있다.
    • List 아규먼트로 여러파일을 참조할 수 도 있다.
  • 파일 업로드 form
  • <form method="POST" enctype="multipart/form-data" action="#" th:action="@{/file}"> File:<input type="file" name="file"/> <input type="submit" value="Upload"/> </form>
  • 파일 업로드 처리 핸들러
  • @PostMapping("/file") public String uploadFile(@RequestParam MultipartFile file, RedirectAttributes attributes) { //save String message = file.getOriginalFilename() + " is uploaded."; System.out.println(message); attributes.addFlashAttribute("message", message); return "redirect:/events/list"; }
  • Test
    • MockMultipartFile 사용
      • name : multipartFile form의 파라미터 이름
      • originalFileName : 파일의 이름
      • contentType
      • content
    • new MockMultipartFile("name", "originalFileName", "text/plain", "content".getBytes());

핸들러 메소드 : ResponseEntity

  • 파일 리소스를 읽어오는 방법
    • 스프링 ResourceLoader 사용하기
    • Resource resource = resourceLoader.getResource("classpath:" + fileName);
  • 파일 다운로드 응답 헤더에 설정할 내용
  • @GetMapping("/file/{filename}") @ResponseBody public ResponseEntity<Resource> downloadFile(@PathVariable String filename) throws IOException { Resource resource = resourceLoader.getResource("classpath:" + filename); File file = resource.getFile(); Tika tika = new Tika(); String type = tika.detect(file); return ResponseEntity.ok() .header(HttpHeaders.CONTENT_DISPOSITION, "attachement; filename=\"" + resource.getFilename() + "\"") .header(HttpHeaders.CONTENT_TYPE, type) .header(HttpHeaders.CONTENT_LENGTH, String.valueOf(file.length())) .body(resource); }

참고


핸들러 메소드 : @RequestBody & HttpEntity

  • @RequestBody
    • 요청 본문(body)에 들어있는 데이터를 HttpMessageConverter를 통해 변환한 객체로 받아올 수 있다.
    • @Valid 또는 @Validated를 사용해서 값을 검증할 수 있다.
    • BindingResult 아규먼트를 사용해 코드로 바인딩 또는 검증 에러를 확인할 수 있다.
  • HttpMessageConverter
    • 스프링 MVC 설정 (WebMvcConfigurer)에서 설정할 수 있다.
      • WebMvcConfigurer.configureMessageConverters()
        • 기본 메세지 컨버터를 대체 기본 컨버터들이 등록되지 않게됨으로 가급적 사용하지 않는것이 좋을듯하다.
      • WebMvcConfigurer.extendMessageConverters()
        • 기본 메세지 컨버터에 추가
      • 기본 컨버터가 WebMvcConfirationSupport.addDefaultHttpMessageConverters() 에 의해 등록된다.
  • 요청헤더로부터 Content Type을 읽어서 핸들러 어댑터가 여러 컨버터중에 컨버팅할 수 있는 컨버터를 선택하여 컨버트를 한다.
  • HttpEntity
    • @RequestBody 와 비슷하지만 추가적으로 요청 헤더 정보를 사용할 수 있다.

핸들러 메소드 @ResponseBody & ResponseEntity

  • @ResponseBody
    • 데이터를 HttpMessageConverter를 사용해 응답 본문 메세지로 보낼 때 사용한다.
    • @RestController 사용 시, 자동으로 모든 핸들러 메소드에 적용된다.
  • ResponseEntity
    • 응답 헤더 상태 코드 본문을 직접 다루고 싶은 경우에 사용한다.

@JsonView

  • ViewClass
  • public class JsonViewClass { interface Simple {} interface Complex extends Simple {}}
  • Entity class
  • public class Entity { @JsonView(JsonView.Simple.class) private String name; @JsonView(JsonView.Simple.class) private int age; @JsonView(JsonView.Complex.class) private String etc;}
  • 필드에 설정 시, 해당 값만 보여준다.
  • 상속도 가능하다.
  • spring.jackson.mapper.default-view-inclusion=false
    • 기본값
    • true 로 변경 시, JsonView를 설정해도 다른 필드값이 보여진다.

728x90
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday