2011-03-21 56 views
1

我想验证Spring 3 MVC表单。当元素无效时,我想用验证消息重新显示表单。迄今为止这非常简单。蹭的是,当用户在无效提交后点击刷新时,我不希望他们发布POST,我希望他们GET。这意味着我需要从POST(提交)表单重做一个重定向来重新显示带有验证消息的表单(表单通过POST提交)。Spring MVC验证 - 避免POST回

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

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

回答

1

为了解决这个问题,我在一个POST重定向之后将错误对象存储在会话中。然后,在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); 
      } 
     } 
    } 
} 
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检查,如果需要有窗体上的任何错误和显示。

+0

不,我打算对GET和POST使用不同的方法。我想我的问题一定不清楚。我会编辑它。 – 2011-03-24 20:42:47

0

这种方法被称为PRG(POST /重定向/ GET)设计模式,我解释了它在几天前的一个答案:

Spring MVC Simple Redirect Controller Example

希望它能帮助:)

+0

对不起,这不是我要找的。您的示例适用于标准表单提交。我正在查看显示回用户的无效表单。当用户点击刷新时,我不希望他们发布,我希望他们获得。 – 2011-03-24 20:41:03