Сохранение состояния модели с помощью шаблона Post / Redirect / Get - PullRequest
7 голосов
/ 17 февраля 2012

В данный момент я пытаюсь реализовать шаблон Post / Redirect / Get с помощью Spring MVC 3.1. Как правильно сохранить и восстановить данные модели + ошибки проверки? Я знаю, что могу сохранить модель и BindingResult с помощью RedirectAttributes в моем методе POST. Но как правильно восстановить их в методе GET из области флеш-памяти?

Я сделал следующее для POST:

    @RequestMapping(value = "/user/create", method = RequestMethod.POST)
public String doCreate(@ModelAttribute("user") @Valid User user, BindingResult result, RedirectAttributes rA){

    if(result.hasErrors()){
        rA.addFlashAttribute("result", result);
        rA.addFlashAttribute("user", user);

        return "redirect:/user";
    }

    return "redirect:/user/success";
}

И следующее, чтобы получить форму создания пользователя:

    @RequestMapping(value = "/user", method = RequestMethod.GET)
public ModelAndView showUserForm(@ModelAttribute("user") User user, ModelAndView model){

    model.addObject("user", user);
    model.setViewName("userForm");

    return model;
}

Это позволяет мне сохранить данные пользователя в случае ошибки. Но как правильно исправить ошибки? (BindingResult) Я хотел бы показать их в форме с тегами пружинной формы:

<form:errors path="*" />

Кроме того, было бы интересно, как получить доступ к области флеш-памяти из метода get?

Ответы [ 3 ]

3 голосов
/ 23 июля 2012
public class BindingHandlerInterceptor extends HandlerInterceptorAdapter {

    public static final String BINDING_RESULT_FLUSH_ATTRIBUTE_KEY = BindingHandlerInterceptor.class.getName() + ".flashBindingResult";

    private static final String METHOD_GET = "GET";
    private static final String METHOD_POST = "POST";


    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {


        if(METHOD_POST.equals(request.getMethod())) {

            BindingResult bindingResult = getBindingResult(modelAndView);

            FlashMap outFlash = RequestContextUtils.getOutputFlashMap(request);

            if(bindingResult == null || ! bindingResult.hasErrors() || outFlash == null ) {
                return;
            }

            outFlash.put(BINDING_RESULT_FLUSH_ATTRIBUTE_KEY, bindingResult);

        }

        Map<String, ?> inFlash = RequestContextUtils.getInputFlashMap(request);

        if(METHOD_GET.equals(request.getMethod()) && inFlash != null && inFlash.containsKey(BINDING_RESULT_FLUSH_ATTRIBUTE_KEY)) {

            BindingResult flashBindingResult = (BindingResult)inFlash.get(BINDING_RESULT_FLUSH_ATTRIBUTE_KEY);

            if(flashBindingResult != null) {

                BindingResult bindingResult = getBindingResult(modelAndView);

                if(bindingResult == null) {
                    return;
                }

                bindingResult.addAllErrors(flashBindingResult);

            }

        }

    }

    public static BindingResult getBindingResult(ModelAndView modelAndView) {

        if(modelAndView == null) {
            return null;
        }

        for (Entry<String,?> key : modelAndView.getModel().entrySet()) {
            if(key.getKey().startsWith(BindingResult.MODEL_KEY_PREFIX)) {
                return (BindingResult)key.getValue();
            }
        }

        return null;
    }


}
1 голос
/ 20 февраля 2012

Почему вы не показываете форму обновления после сбоя привязки, чтобы пользователь мог попытаться повторно отправить форму?

Стандартный подход для этого, по-видимому, заключается в возвращении представления формы обновления из метода обработчика POST.

if (bindingResult.hasErrors()) {
  uiModel.addAttribute("user", user);
  return "user/create";
}

После этого вы можете отобразить ошибки в форме: тег ошибки.

0 голосов
/ 25 февраля 2012

как правильно восстановить их в методе GET из области флеш-памяти

Я не уверен, что понимаю, что вы имеете в виду, восстанавливая их.То, что вы добавляете как атрибуты flash до перенаправления, будет в модели после перенаправления.Для этого нет ничего особенного.Я так понимаю, вы пытаетесь спросить что-то еще, но я не уверен, что это такое.

Как сказал Фан, почему вы перенаправляете на ошибку?Обычный способ справиться с этим - перенаправить на успех.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...