ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 핸들러 메소드 - 2 (스프링 MVC - 6)
    Programming/Spring MVC 2020. 3. 26. 17:47
    728x90

     

    1. @SessionAttributes

    - 모델 정보를 HTTP 세션에 저장해주는 애노테이션

    - 이 애노테이션에 설정한 이름에 해당하는 모델 정보를 자동으로 세션에 넣어준다.

    - @ModelAttribute는 세션에 있는 데이터도 바인딩한다.

    - 여러 화면에서 사용해야 하는 객체를 공유할 때 사용함

       ex) 회원 가입을 여러 창에 나누어서 할 때

    - SessionStatus를 사용해서 세션 처리 완료를 알려줄 수 있다. (폼 처리가 끝나고 세션을 비울 때 사용)

     

     

    2. @SessionAttribute

    - 해당 컨트롤러 안에서 동작하는 @SessionAttributes와는 다르게 쓰임 

      -> @SessionAttribute는 컨트롤러 밖 (인터셉터 또는 필터 등)에서 만들어 준 세션 데이터에 접근할 때 사용함

    - HTTP 세션에 들어있는 값 참조할 때 사용

     

     

    세션을 사용해서 여러 폼에 걸쳐 데이터를 나눠 입력 받고 저장하기 (@SessionAttributes)

    - 이벤트 이름 입력 -> 이벤트 아이디 입력 -> 이벤트 목록

     

    사용자 최초 접근 시간을 핸들러 인터셉터로 구현하기 (@SessionAttribute)

     

    1) 컨트롤러 작성

    @Controller
    @SessionAttributes("event")
    public class SampleController {
    
        private List<Event> eventList = new ArrayList<>();
    
        @GetMapping("/events/form/name")
        public String eventsFormName(Model model) {
            model.addAttribute("event", new Event());
            return "/events/form-name";
        }
    
        @PostMapping("/events/form/name")
        public String eventsFromNameSumit(@Valid @ModelAttribute Event event,
                                          BindingResult bindingResult) {
            if(bindingResult.hasErrors()){
                return "events/form-name";
            }
            return "redirect:/events/form/id";
        }
    
        @GetMapping("/events/form/id")
        public String eventsFormId(@ModelAttribute Event event,
                                   Model model) {
            model.addAttribute(event);
            return "/events/form-id";
        }
    
        @PostMapping("/events/form/id")
        public String eventFormIdSubmit(@Valid @ModelAttribute Event event,
                                        BindingResult bindingResult,
                                        SessionStatus sessionStatus) {
            if(bindingResult.hasErrors()){
                return "/events/form-id";
            }
    
            // Store to Database
            eventList.add(event);
            sessionStatus.setComplete();
            return "redirect:/events/list";
        }
    
        @GetMapping("/events/list")
        public String showEvents(Model model, @SessionAttribute LocalDateTime visitTime) {
            System.out.println(visitTime);
    
            // Select from database
            model.addAttribute(eventList);
            return "/events/list";
        }
    }
    

     

    2) 핸들러 인터셉터 작성 및 등록(등록은 생략)

    public class VisitTimeInterceptor implements HandlerInterceptor {
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
            final HttpSession session = request.getSession();
            if(session.getAttribute("visitTime") == null) {
                session.setAttribute("visitTime", LocalDateTime.now());
            }
    
            return true;
        }
    
    }
    

     

     

    3. RedirectAttributes

    - 리다이렉트 할 때 기본적으로 Model에 들어있는 primitive type 데이터는 URI 쿼리 매개변수에 추가된다.

       스프링 부트에서는 이 기능이 기본적으로 비활성화 되어 있다. (프로퍼티 추가하여 활성화)

    - 원하는 값만 리다이렉트 할 때 전달하고 싶다면 RedirectAttributes에 명시적으로 추가 가능 

    - 리다이렉트 요청을 처리하는 곳에서 @RequestParam, @ModelAttribute (세션 사용 시 이름 같으면 안됨)로 받을 수 있음

    - Event와 같은 객체 전달 불가능

     

     

    4. Flash Attributes

    - 주로 리다이렉트시에 데이터를 전달할 때 사용한다.

    - 데이터가 URI에 노출되지 않는다

    - 임의의 객체를 저장할 수 있다.

     

    리다이렉트 하기 전에 데이터를 HTTP 세션에 저장하고 리다이렉트 요청을 처리 한 다음 그 즉시 제거한다.

    redirectAttributes.addFlashAttribute(event);

     

    리다이렉트를 받는 핸들러는 Model로 위의 객체를 받을 수 있음.

     

     

    5. MultipartFile

    - 파일 업로드 시 사용하는 메소드 아규먼트

    - MultipartResolver 빈이 설정 되어 있어야 사용할 수 있다 (스프링 부트 자동 설정이 해줌)

    - POST multipart/form-data 요청에 들어있는 파일 참조 가능

    - List<MultipartFile> 아규먼트로 여러 파일을 참조할 수 있다.

     

    1) 업로드 및 업로드 확인 페이지 작성

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8"></meta>
        <title>Title</title>
    </head>
    <body>
        <div th:if="${message}">
            <h2 th:text="${message}">msg</h2>
        </div>
    
        <form method="POST" enctype="multipart/form-data" action="#" th:action="@{/file}">
            <input type="file" name="file"></input>
            <input type="submit" value="UPLOAD"></input>
        </form>
    </body>
    </html>

     

    2) FileController 작성

    @Controller
    public class FileController {
    
        @GetMapping("/file")
        public String fileForm(Model model) {
            return "/files/index";
        }
    
        @PostMapping("/file")
        public String fileUpload(@RequestParam MultipartFile file,
                                 RedirectAttributes redirectAttributes) {
    
            /*
            	save
                local, cloud..에 저장
            */
    
            String message = file.getOriginalFilename() + " is Uploaded";
            redirectAttributes.addFlashAttribute("message", message);
            return "redirect:/file";
        }
    }
    

     

     

    6. 파일 다운로드

     

    파일 리소스 읽어오는 방법

    - 스프링 ResourceLoader 사용하기

     

    파일의 종류(미디어 타입) 알아내는 방법

    - 티카 의존성 추가 후 사용

     

    ResponseEntity

    - 응답 상태 코드

    - 응답 헤더

    - 응답 본문

     

    @Controller
    public class FileController {
    
        @Autowired
        ResourceLoader resourceLoader;
    
        @GetMapping("/file/{filename}")
        public ResponseEntity<Resource> fileDownload(@PathVariable String filename) throws IOException {
            Resource resource = resourceLoader.getResource("classpath:" + filename);
            File file = resource.getFile();
    
            return ResponseEntity.ok()
                    .header(HttpHeaders.CONTENT_DISPOSITION,
                            "attachment; filename=\"" + resource.getFilename() + "\"")
                    .header(HttpHeaders.CONTENT_TYPE, "text/plain")
                    .header(HttpHeaders.CONTENT_LENGTH, file.length() + "")
                    .body(resource);
        }
    
    }
    

     

     

    7. @RequestBody & HttpEntity

     

    @ReqeustBody

    - 요청 본문(body)에 들어있는 데이터를 HttpMessageConverter를 통해 변환한 객체로 받아올 수 있음

    - @Valid, @Validated 사용해서 검증 할 수 있음

    - BindingResult 사용 가능 (바인딩 예외 발생 시 예외를 발생시키지 않고, 코드로 처리할 수 있음)

     

    HttpEntity

    - @RequestBody와 비슷하지만 추가적으로 요청 헤더 정보를 사용할 수 있다.

     

     

    8. @ResponseBody & ResponseEntity

     

    @ResponseBody

    - 데이터를 HttpMessageConverter를 사용해 응답 본문 메시지로 보낼 때 사용함

    - @RestController 사용 시 자동으로 모든 핸들러 메소드에 적용됨

     

    ResponseEntity

    - 응답 헤더 상태 코드 본문을 직접 다루고 싶은 경우에 사용함

     

     

    -@JsonView, PushBuilder는 따로 공부할 것!

     

     

     

     

    인프런 백기선님 '스프링 MVC’ 강의를 듣고 정리한 내용입니다.
    728x90

    댓글

Designed by Tistory.