Estragon
Estragon

Reputation: 1462

struts2 prepare and validation

Im trying to ensure that when an action is called, the expected parameters are given (like to show a user profile I want to be sure that parameters contains the user id : viewUser.action?userId=1 should work well but viewUser.action should redirect to an error page)

So I created a validation xml that specifies that the userId field can not be null. Everything works fine.

But now, on prepare() I do some pre-work using the userId. The fact is that prepare interceptor is called before validation interceptor so if userId is null then I have a nice nullPointerException and the validation is not called because the error happened before. I know I can switch the interceptor order but I don't want to.

So my question is : Im I supposed to use parameters inside prepare() methods ? Is there any other way to handle that ?

Thanks and sorry for my bad english :(

Upvotes: 0

Views: 2282

Answers (3)

Quaternion
Quaternion

Reputation: 10458

What follows is an explanation as to how to avoid this issue and make over all development easier however the most immediate solution is most certainly Daves. I would definitely implement that first and be done with the issue and use the following in the future.

In my experience prepare() is used to acquire services which will let the action do it's job which is best served by Dependency Injection (Spring).

Generally the action class is responsible for the following:

  • Getting objects needed to perform the action (service objects).
  • Getting parameters needed to perform the action(used by the service objects to get what we need).
  • Verifying the parameters make sense (validation method/annotations, could externalise to xml).
  • Performing the action (using the service objects previously mentioned).
  • Getting the objects needed for the view...

This you know and you also know that prepare is about getting the objects needed to perform the action (ideally service objects although some people do things like opening up DB connections). The actual doing should be restricted to the execute method.

Going with the ideal route, which is using service objects injected with your DI provider of choice (Spring/Guice), we find our selves having little to no reason to need the prepare method at all. Our actions get smaller, easier to understand and easier to test as a result.

Upvotes: 0

Vasily Komarov
Vasily Komarov

Reputation: 1415

Your can change default order of the interceptors in your struts-default.xml file, so checkbox and params interceptors will start before prepare interceptor.

<interceptor-stack name="basicStack">
  <interceptor-ref name="exception"/>
  <interceptor-ref name="servletConfig"/>
  <interceptor-ref name="checkbox"/>
  <interceptor-ref name="params"/>
  <interceptor-ref name="prepare"/>
  <interceptor-ref name="conversionError"/>
</interceptor-stack>

But i don't like this idea. I thing the better way is to change your action logic and remove all parts of code from prepare function if they use some parameters. Why your do it in "prepare"? Your want to use the results during validation?

Upvotes: 0

Dave Newton
Dave Newton

Reputation: 160181

Use the "paramsPrepareParamsStack" interceptor stack.

Upvotes: 1

Related Questions