Hi Marcelo,

This is an interesting problem. It does seem that preserving the errors across redirects will require storing them in the session (or in something session-scoped like the page flow instance), or encoding them into the URL. Assuming that URL-encoding the messages is unrealistic, your approach seems reasonable to me.

Anyone else see something I'm missing here? Marcelo, is there anything in the framework that would make this more graceful from your perspective?

Rich

p.s. Sorry for the late reply -- I lost track of this message early on.


Marcelo Morales wrote:
Helo

I came up with a solution to my own problem. I'm not sure if this is final. I still seems a little ugly

The solution came from two Interceptors.

public class MyRequestInterceptor extends RequestInterceptor {

public void preRequest(RequestInterceptorContext requestInterceptorContext, InterceptorChain interceptorChain) throws InterceptorException { HttpServletRequest request = requestInterceptorContext.getRequest(); Object fromVal = request.getSession().getAttribute("com.redcetus.errores.intermedios");
        request.setAttribute(Globals.ERROR_KEY, fromVal);
request.getSession().removeAttribute("com.redcetus.errores.intermedios");
        interceptorChain.continueChain();
    }

public void postRequest(RequestInterceptorContext requestInterceptorContext, InterceptorChain interceptorChain) throws InterceptorException { HttpServletRequest request = requestInterceptorContext.getRequest(); ActionMessages retValue = (ActionMessages) request.getAttribute(Globals.ERROR_KEY);
        if ((retValue == null) || retValue.isEmpty()) {
request.getSession().removeAttribute("com.redcetus.errores.intermedios"); } else if (request.getAttribute("com.redcetus.redirected") == null || Boolean.TRUE.equals(request.getAttribute("com.redcetus.redirected"))) { request.getSession().setAttribute("com.redcetus.errores.intermedios", retValue);
        }

        interceptorChain.continueChain();
    }

}

public class MyActionInterceptor extends ActionInterceptor {
public void afterNestedIntercept(AfterNestedInterceptContext afterNestedInterceptContext) throws InterceptorException {
    }

public void preAction(ActionInterceptorContext actionInterceptorContext, InterceptorChain interceptorChain) throws InterceptorException {
        interceptorChain.continueChain();
    }

public void postAction(ActionInterceptorContext actionInterceptorContext, InterceptorChain interceptorChain) throws InterceptorException { HttpServletRequest request = actionInterceptorContext.getRequest(); if (actionInterceptorContext.getOriginalForward().getRedirect()) { request.setAttribute("com.redcetus.redirected", Boolean.TRUE);
        } else {
request.setAttribute("com.redcetus.redirected", Boolean.FALSE);
        }
        interceptorChain.continueChain();
    }
}

What do you think about this?, is it the "beehive way"?


Best regards

Marcelo Morales



On Feb 26, 2006, at 3:52 PM, Marcelo Morales wrote:

Helo

I will be grateful if you help me solve this one.

This is a typical action inside an application:

    @Jpf.Action(
        forwards = {
            @Jpf.Forward(name="success", action="mypage")
        },
        useFormBean = "myForm",
        validatableProperties = {
            @Jpf.ValidatableProperty(
                propertyName = "name",
                displayName = "Name",
                validateRequired = @Jpf.ValidateRequired(),
                validateMinLength = @Jpf.ValidateMinLength(chars = 5),
                validateMaxLength = @Jpf.ValidateMaxLength(chars = 32))
        },
validationErrorForward = @Jpf.Forward(name="fail", action="mypage")
    )
    public Forward myaction(Form form) {
        /* Some stuff gets done... */
        addActionError("name", "name.is.ok", new Object[] {});
        return new Forward("success");
    }

mypage is a simple action that just forwards the request to a tiles definition.

Now I want to make all POST redirected, following the Redirect After Post idea (http://www.theserverside.com/articles/article.tss?l=RedirectAfterPost). So I have changed the forwards like this:

@Jpf.Forward(name="success", action="mypage")
to
@Jpf.Forward(name="success", action="mypage", redirect=true)

and from
validationErrorForward = @Jpf.Forward(name="fail", action="mypage")
to
validationErrorForward = @Jpf.Forward(name="fail", action="mypage", redirect=true)

and i coded the beforeAction and afterAction methods in the Controller so i save all messages on the session (when i'm about to send the redirection) and retrieve them when i am going to show them.

This works for the "name.is.ok" message, which gets inserted on the action; but it does not work for the validation messages because the beforeAction and afterAction methods don't get executed when validation fails.

How can i keep the validation messages on the session so i can show them afterwards?

I was thinking about hacking the validate method in AnyBeanActionForm.java to put all ActionErrors on the session as well, but i think this is too intrusive. I am also looking at the ActionInterceptor and RequestInterceptor classes (i am about to run the samples).

Thanks in advance

Marcelo Morales




Reply via email to