在 Java 世界中实现类似 Rails 的 flash 消息(例如“更新成功” http://api.rubyonrails.org/classes/ActionController/Flash.html )的最佳方法是什么?我正在使用 Spring MVC。
5 回答
我已经在 Spring MVC 中使用会话范围的bean 做到了这一点。
public class FlashImpl implements Flash, Serializable{
private static final long serialVersionUID = 1L;
private static final String ERROR = "error";
private static final String WARNING = "warning";
private static final String NOTICE = "notice";
private String message;
private String klass;
public void message(String klass, String message) {
this.klass = klass;
this.message = message;
}
public void notice(String message) {
this.message(NOTICE, message);
}
public void warning(String message) {
this.message(WARNING, message);
}
public void error(String message) {
this.message(ERROR, message);
}
public boolean isEmptyMessage() {
return message == null;
}
public void clear() {
this.message = null;
this.klass = null;
}
public String getMessage() {
String msg = message;
this.clear();
return msg;
}
public void setMessage(String message) {
this.message = message;
}
public String getKlass() {
return klass;
}
public void setKlass(String klass) {
this.klass = klass;
}}
诀窍是在第一次阅读该消息后立即使用它。这样,它可以在发布后生存到重定向。
我假设只有一种类型的请求消息!如果你不想要这个,你可以按照已经建议的那样创建一个哈希图。
我将这个 bean 注入到我的控制器中(实际上我将它注入到一个由所有其他控制器继承的基本控制器中)。
在您的 JSP 中,您必须添加如下代码:
<c:if test="${!flash.emptyMessage}" >
<div class="${flash.klass}">${fn:escapeXml(flash.message)}</div>
</c:if>
我建议将其实现为会话范围的 HashTable,将字符串键映射到自定义 FlashItem 对象。FlashItem 将仅包含您正在存储的对象或字符串以及一个布尔值,可能称为 IsNew,当您将新项目插入 HashTable 时,该值应设置为 true。
然后在每个页面加载时迭代 HashTable,将任何 IsNew = true 项设置为 false,并删除 IsNew 已经为 false 的所有项。这应该给你一个与 Rails 的 flash 功能类似的工作。
这已添加到 Spring MVC 3.1.RC1:
Flash 属性现在可以存储在 FlashMap 中,并保存在 HTTP 会话中以在重定向中存活。有关 Spring MVC 中对 flash 属性的一般支持的概述,请参阅第 16.6 节,“使用 flash 属性”</a>。
在带注释的控制器中,@RequestMapping 方法可以通过声明 RedirectAttributes 类型的方法参数来添加 flash 属性。此方法参数现在还可用于精确控制重定向场景中使用的属性。有关更多详细信息,请参阅第 16.3.3.10 节,“指定重定向和 flash 属性”</a>。
我在 Spring MVC 中使用了 Manolo Santos 的示例,如下所示:
使用 @Component 注释 Flash 类,并添加一个布尔变量来指示消息是否应该为另一个请求而存在。
@零件 公共类闪存{ 私人静态最终字符串信息=“信息”; 私人静态最终字符串成功=“成功”; 私有静态最终字符串错误=“错误”; 私有静态最终字符串警告=“警告”; 私有静态最终字符串 NOTICE = "notice"; 私有最终映射消息 = 新 HashMap(); 私有布尔 isKept;// 为另一个请求保留 msg(当控制器方法重定向到另一个请求时) 私人无效消息(字符串严重性,字符串消息){ msgs.put(消息,严重性); } 公共无效信息(字符串消息){ this.message(信息,消息); } 公共无效成功(字符串消息){ this.message(成功,消息); } 公共无效通知(字符串消息){ this.message(注意,消息); } 公共无效警告(字符串消息){ this.message(警告,消息); } 公共无效错误(字符串消息){ this.message(错误,消息); } 公共布尔 isEmptyMessage() { 返回 msgs.isEmpty(); } 公共无效清除(){ msgs.clear(); isKept = 假; } 公共地图getMessage(){ 返回消息; } 公共布尔 isKept() { 返回被保留; } 公共无效保持(){ isKept =真; } 公共无效 unKeep() { isKept = 假; } }
使用拦截器将 Flash 消息添加到模型对象。
公共类 FlashMessageInterceptor 扩展 HandlerInterceptorAdapter { @资源 闪闪; @覆盖 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { if (!flash.isKept()) { modelAndView.addObject("flash", flash); } } @覆盖 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { 如果 (flash.isKept()) { flash.unKeep(); } 别的 { flash.clear(); } } }
在您的控制器中,如果您有一个重定向到另一个方法的方法,您可以说;flush.keep(),显示 flash 消息。
@控制器 公共课 ComputerCampLove { @资源 私人闪闪; @RequestMapping(方法 = RequestMethod.GET) 公共字符串 takeMeToAnotherPlace(模型模型){ flash.info("发-发-发!"); flash.keep(); 返回“重定向:某处”; } }
如果你还没有在你的 spring java 应用程序上投入大量的工作,你可以看看在 jruby 上运行 rails。在 Rails 上运行 jRuby 的美妙之处在于您可以混合和匹配 ruby gem 和 java 库。
如果您已经在您的应用程序中投入了大量工作,那么这很可能不是一个选择。