You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@beehive.apache.org by Rich Feit <ri...@gmail.com> on 2006/04/06 22:41:07 UTC

Re: Keeping validation errors after redirect

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