-
핸들러 메소드 - 2 (스프링 MVC - 6)Programming/Spring MVC 2020. 3. 26. 17:47728x90
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'Programming > Spring MVC' 카테고리의 다른 글
모델, 바인더, 예외 처리, 전역 컨트롤러 (스프링 MVC - 7) (0) 2020.03.26 핸들러 메소드 - 1 (스프링 MVC - 5) (0) 2020.03.24 요청 맵핑하기 (스프링 MVC - 4) (0) 2020.03.24 WebMvcConfigurer (스프링 MVC - 3) (0) 2020.03.22 서블릿 애플리케이션 (스프링 MVC - 2) (0) 2020.03.22