views:

354

answers:

3

What's the best way to achieve Rails-like flash messages such as "Update successful" http://api.rubyonrails.org/classes/ActionController/Flash.html) in the Java world? I'm using Spring MVC.

+4  A: 

I would recommend implementing this as a session-wide HashTable, with string keys mapping to custom FlashItem objects. The FlashItem will simply contain the object or string you're storing plus a boolean value, possibly called IsNew, which should be set to true when you insert a new item into the HashTable.

On each page load you then iterate the HashTable, set any IsNew = true items to false, and delete any items where IsNew is already false. That should give you a work-alike to Rails's flash feature.

Adam Alexander
A: 

If you have not invested a huge amount of work into your spring java app, you could look at running rails on jruby. The beauty of running jRuby on Rails is that you can mix and match ruby gems and java libs.

If you have already put a fair amount of work into your application then this is more then likely not an option.

Kevin Kaske
Unfortunately I'm quite committed to Spring.
Wachunga
+3  A: 

I have done just that in Spring MVC with a session scoped 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;
}}

The trick is in consumming the message once it's been read for the first time. This way it can survive to a redirect after post.

I am assuming that there will be only one type of message for request!. If you don't want this you could create a hashmap as already suggested.

I inject this bean in my controllers (actually I inject it in a base controller inherited by all the others).

In your JSP you have to add some code like this:

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