Введение
Данная статья описывает реализацию сильно упрощенного процесса бронирования билета в кино. Предполагается, что пользователь вводит данные необходимые для бронирования на нескольких страницах, функционал разделен логически, т.е. на первой странице он вводит данные относящиеся к сеансу, на второй свои личные данные, на третьей — данные для оплаты. Последняя страница — для подтверждения бронирования. Все что пользователь вводит — сохранятся в виде формы в сессии, по окончанию бронирования данные из сессии удаляются.
С чего начать
Сразу оговорюсь, предполагается что Spring MVC уже используется у вас в проекте, jsp используются в виде view.
Пользователь выполняет навигацию в следующем порядке:
- booking.jsp: страница выбора киносеанса
- customer.jsp: страница ввода персональных данных
- payment.jsp: страница ввода платежной информации
- confirmation.jsp: страница подтверждения
Листинг: booking.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%> <html> <head> <title>Booking Start Page</title> </head> <body> <form:form action="/booking/movie" modelAttribute="ticketForm"> Movie ID : <form:input path="movieId"/> <input type="submit"/> </form:form> </body> </html>
Листинг: customer.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%> <html> <head> <title>Customer Page</title> </head> <body> <form:form action="/booking/customer" modelAttribute="ticketForm"> Last Name : <form:input path="lastName"/> <input type="submit"/> </form:form> </body> </html>
Листинг: payment.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%> <html> <head> <title>Payment Page</title> </head> <body> <form:form action="/booking/payment" modelAttribute="ticketForm"> CreditCard Number : <form:input path="creditCardNumber"/> <input type="submit"/> </form:form> </body> </html>
Листинг: confirmation.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Confirmation Page</title> </head> <body> Thank you for your purchase! </body> </html>
Форма:
public class TicketForm { private String movieId; private String lastName; private String creditCardNumber; public String getMovieId() { return movieId; } public void setMovieId(String movieId) { this.movieId = movieId; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getCreditCardNumber() { return creditCardNumber; } public void setCreditCardNumber(String creditCardNumber) { this.creditCardNumber = creditCardNumber; } }
Пример использования аннотации @SessionAttributes в контроллере BookTicketController, теперь типы TicketForm прикрепленные к модели, будут так же сохранены в сессии. @SessionAttributes можно так же использовать с указанием имени атрибута в модели.
import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.util.Assert; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.SessionAttributes; import org.springframework.web.bind.support.SessionStatus; Controller @RequestMapping(value = "/booking") @SessionAttributes(types = TicketForm.class) public class BookTicketController { @RequestMapping(method = RequestMethod.GET) public String start(Model model) { // после выхода из start() форма будет скопирована в http session атрибуты благодаря @SessionAttributes(types = TicketForm.class) model.addAttribute(new TicketForm()); return "booking/booking"; } @RequestMapping(value = "/movie", method = RequestMethod.POST) public String selectMovie(TicketForm ticketForm) { Assert.notNull(ticketForm); Assert.notNull(ticketForm.getMovieId()); return "booking/customer"; } @RequestMapping(value = "/customer", method = RequestMethod.POST) public String enterCustomerData(TicketForm ticketForm) { Assert.notNull(ticketForm); // movieId не передавался с customer.jsp, но он был сохранен в сессии во время selectMovie() Assert.notNull(ticketForm.getMovieId()); Assert.notNull(ticketForm.getLastName()); return "booking/payment"; } @RequestMapping(value = "/payment", method = RequestMethod.POST) public String enterPaymentDetails(TicketForm ticketForm) { // movieId не передавался с customer.jsp, но он был сохранен в сессии во время selectMovie() Assert.notNull(ticketForm.getMovieId()); // lastName не передавался с payment.jsp, но он был сохранен в сессии во время enterCustomerData() Assert.notNull(ticketForm.getLastName()); Assert.notNull(ticketForm.getCreditCardNumber()); return "redirect:/booking/confirmation"; } @RequestMapping(value = "/confirmation", method = RequestMethod.GET) public String confirmation(SessionStatus status) { status.setComplete(); // очищаем Spring Session в целях безопасности личных данных return "booking/confirmation"; } }
В дополнение
Управлять SessionAttributes можно при помощи передачи SessionStatus параметра в метод контроллера.
@RequestMapping(value = "/confirmation", method = RequestMethod.GET) public String confirmation(SessionStatus status) { status.setComplete(); return "booking/confirmation"; }
Вызвав status.setComplete(); вы завершите Spring сессию, SessionAttributes будут удалены, сохранив при этом HTTP сессию.
Автор: mais