스프링 웹 MVC-22.Flash Attributes, MultipartFile(핸들러 메소드)
핸들러 메소드 12부: Flash Attributes
주로 리다이렉트시에 데이터를 전달할 때 사용한다.
- 데이터가 URI에 노출되지 않는다.
- 임의의 객체를 저장할 수 있다.
- 보통 HTTP 세션을 사용한다.
리다이렉트 하기 전에 데이터를 HTTP 세션에 저장하고 리다이렉트 요청을 처리 한 다음 그 즉시 제거한다.
RedirectAttributes를 통해 사용할 수 있다.
XPath
- https://www.w3schools.com/xml/xpath_syntax.asp
- https://www.freeformatter.com/xpath-tester.html#ad-output
사용방법
@PostMapping(value = "/events/form/age")
public String eventsFormAgeSubmit(@Validated @ModelAttribute Event event,
BindingResult bindingResult,
SessionStatus sessionStatus,
RedirectAttributes attributes) {
if(bindingResult.hasErrors()){
return "/events/form-age";
}
sessionStatus.setComplete();
attributes.addFlashAttribute("newEvent", event);
// uri 경로 미노출
// 임의의 객체 사용 가능 (event.class)
return "redirect:/events/list";
}
@GetMapping("/events/list")
public String getEvents(Model model, // 그냥 모델에 들어온다. (addFlashAttribute)
@SessionAttribute LocalDateTime visitTime){
System.out.println(visitTime);
Event event = new Event();
event.setName("jaeuk");
event.setAge(30);
Event newEvent = (Event) model.asMap().get("newEvent"); // model에서 꺼냄
List<Event> eventList = new ArrayList<>();
eventList.add(event);
eventList.add(newEvent);
model.addAttribute(eventList);
return "/events/list";
}
테스트코드
@Test
public void getEvents() throws Exception{
Event newEvent = new Event();
newEvent.setName("my name is jaeuk");
newEvent.setAge(27);
mockMvc.perform(get("/events/list")
.sessionAttr("visitTime", LocalDateTime.now())
.flashAttr("newEvent", newEvent))
.andDo(print())
.andExpect(status().isOk())
// html 본문도 테스트 가능
// p 노드를 전부 셀렉트해서 p 노드가 2개 있는지 확인
.andExpect(xpath("//p").nodeCount(2));
}
핸들러 메소드 13부: MultipartFile
MultipartFile
- 파일 업로드시 사용하는 메소드 아규먼트
- MultipartResolver 빈이 설정 되어 있어야 사용할 수 있다. (부트의 경우는 자동 설정 해 줌)
- POST multipart/form-data 요청에 들어있는 파일을 참조할 수 있다.
- List
아큐먼트로 여러 파일을 참조할 수도 있다.
파일 업로드 관련 스프링 부트 설정
- MultipartAutoConfiguration
- MultipartProperties
참고
- https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-multipart-forms
- https://spring.io/guides/gs/uploading-files/
spring.servlet.multipart.location=
spring.servlet.multipart.file-size-threshold=
... 설정가능
파일 업로드 폼
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>file upload form</title>
</head>
<body>
<div th:if="${message}">
<h2 th:text="${message}"></h2>
</div>
<form method="POST" enctype="multipart/form-data" action="#" th:action="@{/file}">
File: <input type="file" name="file"/>
<input type="submit" value="Upload"/>
</form>
</body>
</html>
파일 업로드 처리 핸들러
@GetMapping("/file")
public String fileUploadForm(Model model){
return "files/index";
}
@PostMapping("/file")
public String fileUpload(@RequestParam MultipartFile file,
RedirectAttributes attributes){
//save
String message = file.getOriginalFilename() + "is uploaded";
attributes.addFlashAttribute("message", message);
return "redirect:/file";
}
테스트
@Test
public void fileUploadTest() throws Exception{
MockMultipartFile file = new MockMultipartFile(
"file",
"test.txt",
"plain/text",
"hello file".getBytes());
this.mockMvc.perform(multipart("/file").file(file))
.andDo(print())
.andExpect(status().is3xxRedirection());
}