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