-
Spring MVC(세션 관리)웹개발/Spring 2020. 7. 28. 03:02
이 내용은 인프런의 스프링 웹 MVC강좌를 참고하여 만들었습니다.
세션 : 네트워크 환경에서 connectionless한 문제를 해결하기 위하여 존재
일정시간동안 같은 사용자로부터 오는 요청을 하나의 상태로 저장
Event class
public class Event { interface ValidateLimit{} interface ValidateName{} private Integer id; @NotBlank(groups = ValidateName.class) private String name; @Min(value = 0, groups = ValidateLimit.class) private Integer limit; public Integer getLimit() { return limit; } public void setLimit(Integer limit) { this.limit = limit; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
form.html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Create New Event</title> </head> <body> <form action = "#" th:action="@{/events}" method="post" th:object="${event}"> <p th:if="${#fields.hasErrors('limit')}" th:errors="*{limit}">Incorrect date</p> <p th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Incorrect date</p> <input type="text" title = "name" th:field="*{id}"/> <input type="text" title = "name" th:field="*{name}"/> <input type="text" title="limit" th:field="*{limit}"> <input type="submit" value="Create"/> </form> </body> </html>
1,기본적인 Session의 생성
@Controller public class SampleController { @GetMapping("/events/form") public String eventsForm(Model model,HttpSession httpSession){ Event newEvent = new Event(); newEvent.setLimit(50); model.addAttribute("event",new Event()); httpSession.setAttribute("event",newEvent); return "events/form"; } }
2, @SessionAttributes어노테이션을 이용하게 되면 model의 name과 세선의 name을 자동적으로 매칭을 시켜주워 Session을 저장시켜 줌
@Controller @SessionAttributes({"event"}) public class SampleController { @GetMapping("/events/form") public String eventsForm(Model model){ Event newEvent = new Event(); newEvent.setLimit(50); model.addAttribute("event",new Event()); return "events/form"; } }
테스트 코드
@RunWith(SpringRunner.class) @WebMvcTest public class SampleControllerTest { @Autowired MockMvc mockMvc; @Test public void testForm() throws Exception{ ResultActions result = mockMvc.perform(get("/events/form")) .andDo(print()) .andExpect(view().name("events/form")) .andExpect(model().attributeExists("event")) .andExpect(request().sessionAttribute("event",notNullValue())) .andExpect(status().isOk()) ; } }
3, 세션의 종료는 SessionStatus를 통하여 종료시킬 수 있다.
@Controller @SessionAttributes({"event"}) public class SampleController { @GetMapping("/events/form") public String eventsForm(Model model){ Event newEvent = new Event(); newEvent.setLimit(50); model.addAttribute("event",new Event()); return "events/form"; } @PostMapping("/events") public String getEvent(SessionStatus sessionStatus) { sessionStatus.setComplete(); return "events/form"; } }
또한, 세션의 시간을 applicaion.properties에 다음과 같은 구문을 추가하여 지속 시간을 설정 할 수 있다.
server.servlet.session.timeout=60s
4,위와 같은 방법을 사용하여 멀티 폼 서블릿을 통하여 세션을 응용 할 수 있다.
form-name.html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Create New Event</title> </head> <body> <form action = "#" th:action="@{/events/form/name}" method="post" th:object="${event}"> <p th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Incorrect date</p> <input type="text" title = "name" th:field="*{name}"/> <input type="submit" value="Create"/> </form> </body> </html>
form-limit.html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Create New Event</title> </head> <body> <form action = "#" th:action="@{/events/form/limit}" method="post" th:object="${event}"> <p th:if="${#fields.hasErrors('limit')}" th:errors="*{limit}">Incorrect date</p> <input type="text" title="limit" th:field="*{limit}"> <input type="submit" value="Create"/> </form> </body> </html>
finish.html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Finish</title> </head> <body> <h1>Finish</h1> </body> </html>
- model이 생성이 되면서 세션에 대한 내용이 바뀌는 것을 구현
- name의 값이 들어간 event객체가 세션에 들어가고 limit 값이 들어간 event객체가 같은 이름의 세션에 들어갔을 때 대체가 됨을 확인 할 수 있다.
@Controller @SessionAttributes({"event"}) public class SampleController { @GetMapping("/events/form") public String eventsForm(Model model){ model.addAttribute("event",new Event()); return "events/form-name"; } @PostMapping("/events/form/name") public String getEvent(@Valid @ModelAttribute Event event, BindingResult bindingResult, Model model, HttpServletRequest request) { model.addAttribute("event",new Event()); //세션이 생성됨 //세션이 만들어졌나 확인하는 작업 HttpSession session = request.getSession(); Event sessionCheck = (Event)session.getAttribute("event"); System.out.println("세션의 name 확인 : " + sessionCheck.getName()); if(bindingResult.hasErrors()){ return "events/form-name"; } return "redirect:/events/form/limit"; } @GetMapping("/events/form/limit") public String eventsForm2(@ModelAttribute Event event, Model model){ model.addAttribute("event",event);//세션의 생성 return "events/form-limit"; } @PostMapping("/events/form/limit") public String getEvent2(@Valid @ModelAttribute Event event, BindingResult bindingResult, Model model, SessionStatus sessionStatus, @SessionAttribute("event") Event eventSession) { if(bindingResult.hasErrors()){ return "events/form-limit"; } System.out.println("세션의 limit 확인 : " + eventSession.getLimit()); sessionStatus.setComplete();//세션이 종료됨 return "redirect:/events/list"; } @GetMapping("/events/list") public String getEvents(){ return "events/finish"; } }
5,Interceptor를 통하여 서블릿이 구동 준비 과정에서 세션을 생성하고 관리 할 수도 있다.
public class VisitTimeSetter implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HttpSession session = request.getSession(); if(session.getAttribute("visitTime") == null){ session.setAttribute("visitTime", LocalDateTime.now()); } return true; } }
@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new VisitTimeSetter()); } @Override public void configurePathMatch(PathMatchConfigurer configurer) { UrlPathHelper urlPathHelper = new UrlPathHelper(); urlPathHelper.setRemoveSemicolonContent(false); configurer.setUrlPathHelper(urlPathHelper); } }
'웹개발 > Spring' 카테고리의 다른 글
Spring MVC(MultipartFile와ResponseEntity) (0) 2020.07.30 Spring MVC(RedirectAttribute) (0) 2020.07.30 Spring MVC(폼 서블릿 오류 해결) (0) 2020.07.28 Spring MVC(@ModelAttribute, @Valid, @Validated) (0) 2020.07.28 Spring MVC(html과의 매핑) (0) 2020.07.28