Spring MVC验证 - 避免回发

时间:2011-03-21 21:36:52

标签: spring-mvc validation

我想验证Spring 3 MVC表单。当元素无效时,我想重新显示带有验证消息的表单。到目前为止,这很简单。问题是,当用户在提交无效后点击刷新时,我不希望他们发布,我希望他们获取。这意味着我需要从表单POST(提交)进行重定向,以重新显示带有验证消息的表单(表单通过POST提交)。

我认为最好的方法是使用SessionAttributeStore.retrieveAttribute来测试表单是否已经在用户的会话中。如果是,请使用商店表单,否则创建一个新表单。

这听起来不错吗?有更好的方法吗?

3 个答案:

答案 0 :(得分:1)

要解决此问题,我在POST上重定向后将Errors对象存储在会话中。然后,在GET上,我把它放回模型中。这里有一些漏洞,但它应该在99.999%的时间内工作。

public class ErrorsRedirectInterceptor extends HandlerInterceptorAdapter {
    private final static Logger log = Logger.getLogger(ErrorsRedirectInterceptor.class);

    private final static String ERRORS_MAP_KEY = ErrorsRedirectInterceptor.class.getName()
            + "-errorsMapKey";

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response,
            Object handler, ModelAndView mav)
        throws Exception 
    {
        if (mav == null) { return; }

        if (request.getMethod().equalsIgnoreCase(HttpMethod.POST.toString())) {
            // POST
            if (log.isDebugEnabled()) { log.debug("Processing POST request"); }
            if (SpringUtils.isRedirect(mav)) {
                Map<String, Errors> sessionErrorsMap = new HashMap<String, Errors>();
                // If there are any Errors in the model, store them in the session
                for (Map.Entry<String, Object> entry : mav.getModel().entrySet()) {
                    Object obj = entry.getValue();
                    if (obj instanceof Errors) {
                        if (log.isDebugEnabled()) { log.debug("Adding errors to session errors map"); }
                        Errors errors = (Errors) obj;
                        sessionErrorsMap.put(entry.getKey(), errors);
                    }
                }
                if (!sessionErrorsMap.isEmpty()) {
                    request.getSession().setAttribute(ERRORS_MAP_KEY, sessionErrorsMap);
                }
            }
        } else if (request.getMethod().equalsIgnoreCase(HttpMethod.GET.toString())) {
            // GET
            if (log.isDebugEnabled()) { log.debug("Processing GET request"); }
            Map<String, Errors> sessionErrorsMap =
                    (Map<String, Errors>) request.getSession().getAttribute(ERRORS_MAP_KEY);
            if (sessionErrorsMap != null) {
                if (log.isDebugEnabled()) { log.debug("Adding all session errors to model"); }
                mav.addAllObjects(sessionErrorsMap);
                request.getSession().removeAttribute(ERRORS_MAP_KEY);
            }
        }
    }
}

答案 1 :(得分:0)

从你的问题不清楚,但听起来你的GET和POST动作被映射到同一个处理程序。在这种情况下,您可以执行以下操作:

if ("POST".equalsIgnoreCase(request.getMethod())) {
    // validate form
    model.addAttribute(form);
    return "redirect:/me.html";
}
model.addAttribute(new MyForm());
return "/me.html";

在JSP中检查表单上是否有任何错误并根据需要显示。

答案 2 :(得分:0)

这种方法被称为PRG(POST / REdirect / GET)设计模式我几天前解释过它作为答案之一:

Spring MVC Simple Redirect Controller Example

希望有所帮助:)