基于Spring MVC的站点上的状态消息(注释控制器)

使用注释控制器在基于Spring MVC的站点上组织状态消息(“您的数据已成功保存/添加/删除”)的最佳方法是什么?

因此,问题在于从控制器中的POST方法发送消息。

正如muanis所提到的,从3.1版开始,最好的方法是使用RedirectAttributes。 我将i18n添加到博客中给出的样本中。 所以这将是一个完整的样本。

@RequestMapping("/users") @Controller public class UsersController { @Autowired private MessageSource messageSource; @RequestMapping(method = RequestMethod.POST, produces = "text/html") public String create(@Valid User user, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest, Locale locale, RedirectAttributes redirectAttributes) { ... ... redirectAttributes.addFlashAttribute("SUCCESS_MESSAGE", messageSource.getMessage("label_user_saved_successfully", new String[] {user.getUserId()}, locale)); return "redirect:/users/" + encodeUrlPathSegment("" + user.getId(), httpServletRequest); } ... ... } 

在消息包中添加适当的消息,比如messages.properties。

 label_user_saved_successfully=Successfully saved user: {0} 

编辑jspx文件以使用相关属性

  
${SUCCESS_MESSAGE}

一种经过validation的方法是对消息使用特殊的闪存范围,这些消息应保留到下一个GET请求之前。

我喜欢使用会话范围的flash对象:

 public interface Flash { void info(String message, Serializable... arguments); void error(String message, Serializable... arguments); Map getMessages(); void reset(); } @Component("flash") @Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES) public class FlashImpl implements Flash { ... } 

一个特殊的MVC拦截器将从flash对象中读取flash值并将它们放在请求范围中:

 public class FlashInterceptor implements WebRequestInterceptor { @Autowired private Flash flash; @Override public void preHandle(WebRequest request) { final Map messages = flash.getMessages(); request.setAttribute("flash", messages, RequestAttributes.SCOPE_REQUEST); for (Map.Entry entry : messages.entrySet()) { final String key = "flash" + entry.getKey(); request.setAttribute(key, entry.getValue(), RequestAttributes.SCOPE_REQUEST); } flash.reset(); } ... } 

现在在您的控制器中,您只需将消息放入“闪存范围”:

 @Conteroller public class ... { @Autowired private Flash flash; @RequestMapping(...) public void doSomething(...) { // do some stuff... flash.info("your.message.key", arg0, arg1, ...); } } 

在您的视图中,您将遍历Flash消息:

  

我希望这可以帮助你。

经过一段时间再次敲击我的头后,我终于成功了。

我使用的是Spring 3.1,它支持通过重定向传递的requestFlashAttributes。

解决我的问题的关键是将返回类型更改为字符串而不是ModelAndView对象。

关于在spring使用flash消息的post很棒(http://www.tikalk.com/java/redirectattributes-new-feature-spring-mvc-31)

您应该保持简单并使用特定的HTTP 1.1状态代码。 因此,对于成功的通话,您将返回200 OK。 在客户端,如果要在控制器返回200时向用户显示特定消息,则在那里显示。

如果您的意思是在一些POST后重新加载页面,您可以在视图中包含一个标志(JSP或速度或您使用的任何内容)。 像这样的事情

    

并且您的消息包应该包含该代码的消息。

如果你做一个AJAX POST提交一些数据(即页面没有重新加载,你需要显示一条消息),你可以

1)让你的JS文件动态(JSP或Velocity,再次)并在那里插入标签(我真的不喜欢这个选项)

要么

2)遵循此链接的建议并使用@ResponseBody将状态对象返回给JS。 在标记为@ResponseBody的对象内,您可以同时显示状态和消息。 例如,在这种情况下使用您的消息包。

在JSP上显示消息的最简单方法是使用包含要显示的消息的作用域(可能是会话,可能是请求)对象。 例如,您可以执行以下操作:

 ... java stuff ... List messages = new ArrayList(); messages.add("some message"); messages.add("some other message"); request.addAttribute("NotableMessages", messages); ... java stuff ... ... jsp and JSTL stuff ...  
  • ${item}
... jsp stuff ...

除了适当的状态代码,您始终可以使用所需的特定消息设置标题。 当然,如果您可以控制控制器的使用方式(即没有第三方),这真的是一个好主意。