Rails flash messages in Java

What is the best way to achieve relational flash messages like Update Successfully http://api.rubyonrails.org/classes/ActionController/Flash.html ) in the Java world? I am using Spring MVC.

+6
java ruby spring-mvc ruby-on-rails
source share
5 answers

I would recommend implementing this as a HashTable for the entire session, with string key mapping for custom FlashItem objects. FlashItem will simply contain the object or string you are storing, plus a Boolean value, possibly called IsNew, which should be set to true when you insert a new item into a HashTable.

On each page load, you then iterate over the HashTable, set any IsNew = true to false, and delete any elements where IsNew is already false. This should enable you to work with the Rails function.

+5
source share

I did just that in Spring MVC with a bean session .

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; }} 

The trick is to complete the message when it was read the first time. In this way, he can survive the redirect after posting.

I assume that there will be only one type of message for the request !. If you do not want this, you can create a hash map as already suggested.

I am inserting this bean into my controllers (in fact, I am inserting it into the base controller inherited by everyone else).

In your JSP you need to add this code:

 <c:if test="${!flash.emptyMessage}" > <div class="${flash.klass}">${fn:escapeXml(flash.message)}</div> </c:if> 
+6
source share

This is added in Spring MVC 3.1.RC1:

3.1.15 Flash attributes and RedirectAttributes attributes

Flash attributes can now be saved in FlashMap and saved in an HTTP session to survive redirection. For an overview of general support for flash attributes in Spring MVC, see Section 16.6, “Using flash attributes” .

On annotated controllers, the @RequestMapping method can add flash attributes by declaring an argument to a method of type RedirectAttributes. This method argument can now also be used to fine-tune the attributes used in the redirect script. See Section 16.3.3.10, “Specifying Redirection and Flash Attributes,” for details.

(JIRA issue: SPR-6464 )

+4
source share

I used the Manolo Santos example with Spring MVC as follows:

Annotate the Flash class with @Component and add a boolean to indicate whether the message should be displayed for another request.

 @Component
 public class Flash {

     private static final String INFO = "info";
     private static final String SUCCESS = "success";
     private static final String ERROR = "error";
     private static final String WARNING = "warning";
     private static final String NOTICE = "notice";

     private final Map msgs = new HashMap ();

     private boolean isKept;  // keep msg for one more request (when the controller method redirects to another)

     private void message (String severity, String message) {
         msgs.put (message, severity);
     }

     public void info (String message) {
         this.message (INFO, message);
     }

     public void success (String message) {
         this.message (SUCCESS, 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 msgs.isEmpty ();
     }

     public void clear () {
         msgs.clear ();
         isKept = false;
     }

     public Map getMessage () {
         return msgs;
     }

     public boolean isKept () {
         return isKept;
     }

     public void keep () {
         isKept = true;
     }

     public void unKeep () {
         isKept = false;
     }
 }

Use the interceptor to add a flash message to the model object.

 public class FlashMessageInterceptor extends HandlerInterceptorAdapter {

     @Resource
     Flash flash

     @Override
     public void postHandle (HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
         if (! flash.isKept ()) {
             modelAndView.addObject ("flash", flash);
         }
     }

     @Override
     public void afterCompletion (HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
         if (flash.isKept ()) {
             flash.unKeep ();
         }
         else {
             flash.clear ();
         }
     }
 }

In your controller, if you have a method that redirects to another method, you can simply say: flush.keep () to display a flash message.

 @Controller
 public class ComputerCampLove {

     @Resource
     private flash flash;

     @RequestMapping (method = RequestMethod.GET)
     public String takeMeToAnotherPlace (Model model) {

         flash.info ("Fa-fa-fa!");
         flash.keep ();

         return "redirect: somewhere";
     }
 }
+2
source share

If you have not invested a huge amount in your spring java application, you can look at the work of rails on jruby. The beauty of running jRuby on Rails is that you can mix and match ruby ​​jewels and java libraries.

If you have already invested enough work in your application, this is probably not an option.

0
source share

All Articles