I have a -validation.xml file to check if the fields of the form are empty and that kind of simple validation. I also have a validate() method (extended from ActionSupport) to check more complicated things. But when I send the form it checks the method before the XML file, so if the fields are empty a NullPointerException appears. At least that's what I think is happening.
So my question is, is there a way to change the order of the validation, so the XML is checked before the method?
EDIT: I had the idea of checking if the String is not null in the validate() method so I can avoid the problem, but I don't think that's the wisest thing to do.
The interceptor does check XML first, but IIRC doesn't stop validation if it find errors. I believe I have a patch for this, controlled with a flag.
I've solved this before by checking for errors in the validate method and not proceeding if errors existed.
The order is always one, that is hardcoded order.
The process of validation is performed by the ValidationInterceptor class (at least version 2.3.8).
This interceptor runs the action through the standard validation framework, which in turn checks the action against any validation rules (found in files such as ActionClass-validation.xml) and adds field-level and action-level error messages (provided that the action implements ValidationAware). This interceptor is often one of the last (or second to last) interceptors applied in a stack, as it assumes that all values have already been set on the action.
This interceptor does nothing if the name of the method being invoked is specified in the excludeMethods parameter. excludeMethods accepts a comma-delimited list of method names. For example, requests to foo!input.action and foo!back.action will be skipped by this interceptor if you set the excludeMethods parameter to "input, back".
The workflow of the action request does not change due to this interceptor. Rather, this interceptor is often used in conjunction with the workflow interceptor.
NOTE: As this method extends off MethodFilterInterceptor, it is capable of deciding if it is applicable only to selective methods in the action class. See MethodFilterInterceptor for more info.
First, it checks if the declarative validation is enabled and do it, then it checks if programmatic validation is enabled and do it.
You can turn on/off each type of validation via the interceptor parameters.
Interceptor parameters:
alwaysInvokeValidate - Defaults to true. If true validate() method will always be invoked, otherwise it will not.
programmatic - Defaults to true. If true and the action is Validateable call validate(), and any method that starts with "validate".
declarative - Defaults to true. Perform validation based on xml or annotations.
Related
I have prepare interceptor in use. In one action class, I have an action method named testSomething(), and I also have an action method named prepareTestSomething().
The problem I'm facing here is that the prepare interceptor would invoke the prepareTestSomething() action method as if it was a preparing method for testSomething(), in which case it is not.
Is there a way to make the prepare interceptor to skip the invocation for certain action methods? Like for validation interceptor, we can use "excludeMethods" parameter.
Prepending the prepare word to an Xxx method is the Struts2 convention to tell the framework that it is the prepare() method for the Xxx action method. From the docs:
if the action class have prepare{MethodName}(), it will be invoked
Instead of doing other voodoos (like excluding methods) in order to make this voodoo work, simply change the method name, it is the only right way to go.
Call it initTestSomething(), initializeTestSomething(), preparzTestSomething()... whatever; but please, don't use a convention trying to make it work for something else. It is just... wrong.
Annotations supposedly are markers/provide metadata, so for example how does the #RolesAllowed annotation in JAX-RS work? This annotation "executes" code since it checks that the user is authenticated and has the required roles, at runtime (when an annotated method is called).
No. There is code that checks if the annotation exists and performs operations based on it. The annotation itself just lies there. The code that performs the checking and operations is executed around the method call.
I have a custom interceptor. I would like this interceptor to run on all action invocations except a few. I would like to program this (for extendibility/clarity) rather than using if/else statements checking the action's name inside the interceptor's intercept() method itself.
I think it might be done with the "exclude method" capacities of Struts2, but I'm stuck with the exact details. I think my interceptor needs to extend the MethodFilterInterceptor, but it has 2 intercept methods and the API is not very helpful in saying what each should do:
protected abstract String doIntercept(ActionInvocation invocation)
Subclasses must override to implement the interceptor logic.
String intercept(ActionInvocation invocation)
Override to handle interception
You are thinking it the other way around:
instead of checking the Action name (or better, the instanceOf to check for a specific Action Interface) to see if it should do some business, simply tell that Action to use a different Interceptor Stack.
For example, you can say that your Custom Stack (the Stack containing your Interceptor) is the default (then applied to all actions), but that ActionA, ActionB and ActionX run with the DefaultStack...
Interceptors shouldn't extend ActionSupport, yuck. They're not actions.
Mark the actions it should (or should not) run for with an interface or annotation and check for that in the interceptor.
I have a form with multiple fields that I would like to validate when the user submits it.
The problem I have is that if one field doesn't bind due to, say, non-numeric characters in a field that should be bound to an int then the validate method in my POJO will not be called. This means that the user will only be shown the error for the field that should have been numeric, but will not show any errors for the other fields as the binding fails before the validate method is called.
I was wondering what is the best way round this? I want to be able to show to the user as many errors as possible, rather than having them fix one, submitting, and it failing again due to another field which didn't show as having an error previously.
I ran into the same issue, but if you look at Play's code you'll see that it's not possible.
github.com/playframework - Form.bind(Map,String[])
Play can only call validate() if it is able to instantiate your POJO. If the binding fails then there's no object to call validate on.
If you want all validation to happen at once then I think you have to either use all annotation-based validators (writing your own as necessary) or handle all of the validation yourself.
I am using Struts 2 and Spring autowiring. Right now, the default strategy is set to by-name, but usually we use the constructor and the fallback works to autowire in properties when only one implementing class is available.
There is one property however that I'd like to wire into an action class that has several implementing classes, so I made the Action a java bean, with the properties as fields that can be set. Unfortunately, the only ways that these will be used (apparently) is if they have a public getter/setter, which also exposes them to the type converter at request time. In other words, if a client adds their name to the request as form fields or parameters, Struts will attempt to write those values to them.
So my question is, is it actually possible to use by-name autowiring without exposing properties like that (which may or may not be a security hazard), or am I better off just using XML and defining the Action as an object with scope prototype?
I did eventually track down the documentation for the ParametersInterceptor which actually lists three ways you can limit what parameters are set by the interceptor.
Configuring excludeParams in the parameter configuration, which is a global regex which applies to all actions (not what I want, also possibly deprecated as it is no longer described in the most recent class docs).
Setting excludeMethods (does the same as the previous, the preferred method for global excludes)
Implementing ParameterNameAware, which is the closest to what I wanted. Here you can whitelist what parameters are used.
In the end, defining the action as a prototype object in the normal Spring configuration seemed to be the most prudent. Letting the action manage what parameters it has means another place where parameters need to be explicitly white listed every time a change is made.