23
May 2015
by
小川 岳史
Spring MVC で Post-Redirect-Get パターンを実装するときのやり方をメモ。
コードは GitHub にもあります。
https://github.com/tagbangers/spring-best-practice...
パターン1:セッションを使わない
package practice.post_redirect_get; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.servlet.mvc.support.RedirectAttributes; @Controller @RequestMapping("/basic") public class BasicExampleController { public static final String FORM_MODEL_KEY = "form"; public static final String ERRORS_MODEL_KEY = BindingResult.MODEL_KEY_PREFIX + FORM_MODEL_KEY; @RequestMapping public String get(Model model) { BasicExampleForm form = (BasicExampleForm) model.asMap().get(FORM_MODEL_KEY); if (form == null) { form = new BasicExampleForm(); } model.addAttribute(FORM_MODEL_KEY, form); return "basic"; } @RequestMapping(method = RequestMethod.POST) public String post( @Validated BasicExampleForm form, BindingResult result, RedirectAttributes redirectAttributes) { redirectAttributes.addFlashAttribute(FORM_MODEL_KEY, form); redirectAttributes.addFlashAttribute(ERRORS_MODEL_KEY, result); if (result.hasErrors()) { return "redirect:/basic"; } // Do something. For example, call a method of a service class. redirectAttributes.getFlashAttributes().clear(); redirectAttributes.addFlashAttribute("message", "Success!"); return "redirect:/basic"; } }
パターン2:セッションを使う
入力ページが複数に渡るウィザードのようなページを作りたい時など。
package practice.post_redirect_get; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.validation.annotation.Validated; import org.springframework.web.HttpSessionRequiredException; import org.springframework.web.bind.annotation.ExceptionHandler; 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.servlet.mvc.support.RedirectAttributes; @Controller @RequestMapping("/session") @SessionAttributes(types = SessionExampleForm.class) public class SessionExampleController { public static final String FORM_MODEL_KEY = "form"; public static final String ERRORS_MODEL_KEY = BindingResult.MODEL_KEY_PREFIX + FORM_MODEL_KEY; @ExceptionHandler(HttpSessionRequiredException.class) public String handleHttpSessionRequiredException(HttpSessionRequiredException exception) { return "redirect:/session?expired"; } @RequestMapping public String init(Model model) { SessionExampleForm form = new SessionExampleForm(); model.addAttribute(FORM_MODEL_KEY, form); return "session-step1"; } @RequestMapping(params = "step1") public String step1(Model model) { SessionExampleForm form = (SessionExampleForm) model.asMap().get(FORM_MODEL_KEY); if (form == null) { form = new SessionExampleForm(); } model.addAttribute(FORM_MODEL_KEY, form); return "session-step1"; } @RequestMapping(params = "step1", method = RequestMethod.POST) public String step1( @Validated SessionExampleForm form, BindingResult result, RedirectAttributes redirectAttributes) { redirectAttributes.addFlashAttribute(FORM_MODEL_KEY, form); redirectAttributes.addFlashAttribute(ERRORS_MODEL_KEY, result); if (result.hasFieldErrors("email")) { return "redirect:/session?step1"; } redirectAttributes.getFlashAttributes().clear(); return "redirect:/session?step2"; } @RequestMapping(params = "step2") public String step2(Model model) throws HttpSessionRequiredException { SessionExampleForm form = (SessionExampleForm) model.asMap().get(FORM_MODEL_KEY); if (form == null) { throw new HttpSessionRequiredException("Expected session attribute '" + FORM_MODEL_KEY + "'"); } model.addAttribute(FORM_MODEL_KEY, form); return "session-step2"; } @RequestMapping(params = "step2", method = RequestMethod.POST) public String step2( @Validated SessionExampleForm form, BindingResult result, RedirectAttributes redirectAttributes) { redirectAttributes.addFlashAttribute(FORM_MODEL_KEY, form); redirectAttributes.addFlashAttribute(ERRORS_MODEL_KEY, result); if (result.hasErrors()) { return "redirect:/session?step2"; } // Do something. For example, call a method of a service class. redirectAttributes.getFlashAttributes().clear(); redirectAttributes.addFlashAttribute("message", "Success!"); return "redirect:/session"; } }