1

If you extend the ValidatorSupport class in Struts 2 can you have instance variables on the class? Can it have state or does it have to be stateless?

I know action classes aren't singletons and can have state but I'm not sure about their associated validators.

I need to know if I can have an instance variable within a validator that extends ValidatorSupport. For example:

public class SomeValidator extends ValidatorSupport {
    private boolean alreadyHasErrorOnPage;

}

If the validators are signlestons, using alreadyHasErrorOnPage since it would result in a race condition and never a consistent default state for each request/response. If they aren't singletons and a new SomeValidator instance is created for each request/response then using alreadyHasErrorOnPage would be safe.

Take the following with a grain of salt because I'm not sure how much of it is specifically related to the project I'm currently working on.

Validators are singles on our project. I went in and debugged the application and found instance members to not be at a default state after a second request/response. Essentially they carry over the value from the first or previous request/response.

The reason I'm still not sure is because our project seems to have wrapped and ValidatorSuppport and exposed an interface that our validators implement. Within our codebase there seems to be code that stores an instance of the validators in a map essentially making them singletons. I haven't been able to determine if stock struts2 behaves in the same manner.

Roman C
  • 49,761
  • 33
  • 66
  • 176
Dan King
  • 1,080
  • 1
  • 11
  • 28
  • What *kind* of state? E.g., validators have state that store config, like a string's max/min length. – Dave Newton Jul 11 '15 at 16:11
  • State about the current session I guess. I'm not too sure how to explain it. The way our validators work is we pass an instance of the action into the validate method. We then use the getters and setters on the action to get the data we want to validate. So I guess my question might be should it store info on the current request/response? Essentially are those classes Singleton's or is their an instance created for each request/response – Dan King Jul 11 '15 at 16:45
  • You pass an instance into the validator when? I mean, validators get the object in their `validate` methods; they're not stored in the validator itself. It's not clear to me what you're trying to do, but I'm suspicious. In any case, it'd be easy enough to test, right? I don't recall off the top of my head, but I'd be surprised if they were created per-request. – Dave Newton Jul 11 '15 at 16:54
  • @DanKing I have found this interesting, but could you elaborate why do you need this information and how it would affect the software you develop? – Roman C Jul 14 '15 at 12:12
  • @RomanC I edited the question with some info about why it matters. I found my answer related to my project but I"m still not sure if this is default struts2 behaviour or a side effect on how we have implemented our validators. – Dan King Jul 15 '15 at 07:04
  • @DanKing If the question is related to your project, then it's off-topic, because you didn't post the code example to reproduce the issue, otherwise if it's regarding struts2 project then my answer remains at power. – Roman C Jul 15 '15 at 08:32

1 Answers1

0

They should have a state, because the state is the subject to validate, that should be set to the validator before it's executed. The validator instance should be built the same way like the actions in Struts2.

The object is passed to the Validator via the validate method. It has a signature

void validate(Object object) throws ValidationException;  

Generally the object is the action instance that you can validate in the method implementation. The validator instance is built via the validator factory. One is used the object factory to build the validator and inject it with container if there are available injectors. But the object factory, what ever implementation you use, just create a new instance and return it. So, each time you use the validator factory to build the validator the new instance is created. Then as you might seen the Validator has properties such as message, messageKey, messageParameters, etc. These properties define the state of the Validator. You can extend the ValidatorSupport with custom properties without fear. Because the new instance of the validator is created each time per validation, then it's thread safe.

Can it have state or does it have to be stateless?

It's already has a state, the stateless bean doesn't have public properties.

Roman C
  • 49,761
  • 33
  • 66
  • 176
  • Validators get the object in their `validate` call, they're not set on the validator itself. – Dave Newton Jul 11 '15 at 16:56
  • @DaveNewton Can't they set an object on the validator itself, why? – Roman C Jul 11 '15 at 19:42
  • Technically you *could*, but since it's already being sent to the `validate` method I'm not sure why you'd *want* to. I honestly don't remember if they're instantiated during app configuration or per-request; if it's per-request that seems like a bunch of overhead since you'd have to re-evaluate the validation params. It's on my list of things to look up :) – Dave Newton Jul 11 '15 at 19:49
  • Anyway it has to re-evaluate, either parameters or fields, I doubt it would make any difference. – Roman C Jul 11 '15 at 20:00
  • Re-evaluating the validator params, though, would mean a re-eval of the config string. Which might be desirable anyway, I suppose, but it should be more work than getting the named field from the action (a normal stack lookup, but by name only). I dunno, I'm still guessing they're not re-created on each request, but it's just a guess at this point. – Dave Newton Jul 11 '15 at 20:03