Struts2 prepare interceptor - How to skip certain methods - java

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.

Related

Listen for a method call

I'm trying to listen to when a method on a class its called.
I have an ArrayList and I want to listen on each item when a method is called (not each method, just the one that I want).
In c# there is something called Action, where I can register methods that will be called when this Action is Invoked, inside a method for example, and also returns parameters to know which item was called etc.
There is something like that in Java?
Take a look at AspectJ (https://www.baeldung.com/aspectj). It allows you to define pointcuts that match your method so that a given code (the advice) is run when your method is called.

Multiple method interceptions in Guice

I am working with Guice's method interception feature. What I need to know is how to properly implement multiple interceptors, of the form:
this.bindInterceptor(Matchers.any(), Matchers.any(), new Interceptor1(), new Interceptor2());
Specifically, if there is an invocation of proceed() in both interceptors, what happens? Does the intercepted method get called twice? Or does the proceed() in the first interceptor invoke the second interceptor, which then invokes the method? Or should only one interceptor have a proceed()?
Thanks
Both interceptors can (and should) call proceed. This way they can be used as independent aspects (i.e. transactions and logging). In fact if you don't call proceed from your outer interceptor then the next interceptor will not fire.
The method interceptors will be called in a stack-like fashion based on the order of the bindInterceptor calls. In your example it would look like this:
Interceptor1 entry
Interceptor1 proceed
Interceptor2 entry
Interceptor2 proceed
Method
Interceptor2 exit
Interceptor1 exit

Struts2 letting an interceptor not run for certain classes

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.

validate() method after validation.xml

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.

Why we need Preparable Interface in Struts2?

We have Interceptor, we have custom interceptor where we can do all that we want to do before or after our action executes.
Then what is the need to use Preparable interface and implement prepare method for it?
Is this another option or there is some specific aim to do like that?
Well Preparable interface act in conjunction with Prepare Interceptor.This interface has one method defined prepare() and as its name suggest this method is responsible to allow the action to prepare itself.
Prepare interceptor calls prepare() on actions which implement Preparable. This interceptor is very useful for any situation where you need to ensure some logic runs before the actual execute method runs.So if you see this is some kind if init for your action class and it makes sure that before the Action's execute or any other method get called, this method prepare your execute method to work fine.
If you see the default-stack define in core, you will come to know that this interceptor is being called before params or workflow interceptor which indicates its purpose.
A typical use of this is to run some logic to load an object from the database so that when parameters are set they can be set on this object. For details read the doc of Prepare interceptor for details how it work closely with Preparable interface.In short Prepare interceptor will come in to act only when action implements Preparable.
Prepare-Interceptor
Prepare interface assures that if object in use is already on value stack then no need to query database it populates form properties using existing object on value stack.

Categories

Resources