I was thinking about adding a new Interface (like validationAware, etc.) for sturts 2. The methods of the interface would be methods that sets specific parameters that has to be present inside the request.
For example, consider this Interface :
public interface MyCustomInterfaceForActions {
/**
* Set a specific parameter into the request
*/
public void setMyParameter1InRequest(HttpServletRequest request, String myParameter);
/**
* Sets another specific parameter into the request
*/
public void setSecondParamInRequest(HttpServletRequest request, String myParameter);
}
The thing is that I don't want to have to "call" the method "setParameterInRequest" in "execute" methods of each actions that implements that interface.
Also, I want to "force" the actions to set specific parameters into the request.
Is there a way to do that without having to call the "set" methods inside all "executes" methods of my actions? For example, can I extend a struts' "actionExecutor" (I made that name up) and change it's behavior to check if the class implements "MyCustomInterfaceForActions" and call the "set" methods if it's the case?
Or better yet, just check to see if the interface is implemented and just add those parameters to the request anyway, without having to implement methods?
Why not simply use the Preparable, interface. This way you can do your initialization in the prepare() method?
Related
I have a 45 step wizard UI (complex domain - insurance). It's implemented in ASP.NET MVC 3. The problem is my action methods have a lot of code to determine what the next step is, depending on user, already collected data, weather forecast ... And even worse, similar code is repeated for the back button functionality. Is there a pattern I can use to abstract this logic? I'm hoping for a way to define the forward steps and get the backward step automatically.
My suggestion is to create an Interface an a class like:
public interface IStepDecisionMaker
{
StepInfo DefineNextPreviousStep(object data);
}
public class StepInfo {
public int NextStepId {get;set;}
public int PreviousStepId {get;set;}
public object Values {get;set;}
}
you can now add a table in a DB or XML where setting all the available steps and per each step assign them a concrete class that implemente the interface IStepDecisionMaker
In you action you can collect the data of the step and with a IoC system or a reflection CreateInstance you can create an instance of the concrete class, call the DefineNextPreviousStep passing the data you need to check and the method can return a class that will tell you what are the next or previous steps
In this way you can achieve several things
your action will have just few lines of code
the logic is not a tons of if then but is inside each class
you can change some conditions directly in the concrete class of a specific step without touch the other part of the code
IMHO
I have two Struts2 actions. I want to use a public method of a action in another action. Is it Ok that I can call an action through new operator and call its public method? (For the sake of reusing some common functionality)
public class OneAction extends ActionSupport{
public void doSomeThing(){
// some code
}
public String execute(){
// some code
}
}
public class AnotherAction extends ActionSupport{
public String execute(){
/* is it ok?*/
new OneAction().doSomeThing();
}
}
(shudder) I would not. I'd refactor the common functionality into a separate class that both can call. But that class would be a POJO, not an Action.
I'd be careful about embedding functionality in Actions. I think they're firmly in the web tier camp. You should do little more than validate and bind parameters into objects, hand them off to POJOs for processing, and package results for return.
I plus-oned #duffymo's answer, but here's some more food for thought.
If the functionality is common across actions, it belongs in either a base action (if web-related), or a utility class (either web-related or not). Which makes the most sense depends a lot on context.
Along those contextual lines, depending on the actual functionality you're talking about, it might make more sense yet somewhere else--in an interceptor, an aspect, a mixin (how to do that depends on the implementation language), etc. Without knowing details, it's difficult to be more specific.
I have a question with respect to returning data inside Struts2 .
Inside my Action class as shown below , i am getting the Records and setting them inside ArrayList .
But could anybody please tell me , how can i return the Obtained ArrayList to the JSP Page ? because with the syntax of the Action class execute method , it allows us to return only a String ?
public class DBDisplay extends ActionSupport{
private String name ;
List list = null;
public String execute() throws Exception
{
list = DBClass.getInstance().list();
Iterator it = list.iterator();
while(it.hasNext())
{
name = (String) it.next();
}
setName(name);
}
public String getname()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
}
Action classes return a string to name the result, not to return data. Data is exposed via either action properties (like the name you already expose) or a model instance (if implementing ModelDriven).
Access to the list is the same as name–by providing a public accessor to the list:
public class DBDisplay extends ActionSupport {
private List list;
public List getList() { return list; }
// Rest of class elided.
}
Then from the JSP, for example:
<s:iterator value="list">
<s:property /><br/>
</s:iterator>
The iterator tag "value" attribute refers to the list action property, and will call getList() on the action. The property tag will access the value on the top of the stack if given no "value" attribute.
You may wish to spend some time looking over the Struts 2 "nutshell" documentation.
One of the fundamental design goals of Struts 2 framework is to bring MVC (Model-View-Controller) design pattern into the Web application development. MVC pattern enables separation of concerns and allows for the clean and loosely coupled code which is easy to maintain.
MVC pattern consists of 3 distinct pieces. Model, View and Controller. Let us see how these three elements are implemented in Struts 2.
Controller (StrutsPrepareAndExecuteFilter) – Controller is the component which handles co-ordination of various requests. In a Web application, different user requests needs to be served by different application components and this decision is taken by the Controller component. In Struts 2, every request to the Web application first reaches the front controller class – StrutsPrepareAndExecuteFilter. This inspects the incoming requests and then routes the request to the appropriate class (known as Action class in Struts) configured to handle the request.
Model (Action) – Model is the component which is responsible for executing application’s business functionality. It is the core of the application. It represents the state of the application and includes business logic and business data. In Struts 2, action classes act as the gateway to an application’s model. These classes are responsible for handling every user request and then delegates business logic to other classes written by the application developer.
Having different action classes for different user requests ensures that we have clean code which can be easily maintained. But what about functionality that is required across different user requests(such as application logging)?. For such cross cutting concerns, Struts 2 has a different component called interceptors.
View (Result) – View in an MVC architecture is the component responsible for the presentation(user interface). View component makes use of the Model component to get data and then display it. Struts 2 supports multiple technologies such as JSP, Velocity templates, FreeMarker, XSLT for View component. In Struts 2 terminology, View is know as the Result. The action class (Model) determines what Result (View) should be presented to the user.
User accesses a Struts 2 application functionality by accessing the application URL in a browser. The request always comes to the StrutsPrepareAndExecuteFilter controller(Since it is configured in the web.xml of all Struts 2 applications). StrutsPrepareAndExecuteFilter looks for the Action class to call in the struts.xml file. Alternatively it can guess it using conventions. Action class execute() method is then invoked which in turn calls the business logic classes.
Action classes can specify the view to display using annotations or it can be specified in the struts.xml file. Either way Struts 2 knows which View (Result) is to be invoked for displaying the data back to the user. Another important thing to note here is that the objects in the Action class is available to the View component. Hence Actions not only determine which View(Result) to display but also provides data required by the View.
The valueStack(it's combination of objectStack and contextMap) OGNL is used to store the action and other objects. You can use OGNL to access the objects stack and Context Map.
OGNL
Bind the elements to modal objects and converts values from one type to another
Bind generic tags with modal objects.
Create lists and maps on the fly, to be used with GUI methods
Invoke methods. you can invoke any method, not only getters and setters.
I have came across an issue where i am unable to find a solution.I am working on a web-application and have to impliment Oauth, things are working fine for me except one issue,in my redirect back URL from Yahoo i am getting several parametersand i need to access few of them in my action class.
Now i can easily create a property in my action class with its getter and setter methods but the name of the property is
openid.response_nonce
and my Eclipse editor will not allow me to name a variable like this.Though one solution is add RequestAware interceptor in my action class and access the parameter.
my Question is can i access it without using RequestAware inteceptor?
There isn't a RequestAware interceptor... There is a Servlet-Config interceptor which will check if your action has one of the following interfaces: ServletContextAware, ServletRequestAware, ServletResponseAware, ParameterAware, RequestAware, SessionAware, ApplicationAware, PrincipalAware.
The Servlet-Config interceptor is part of the default-stack, which you are probably already using. So there is no additional cost or configuration required to use one of the aware interfaces.
That aside, if you have a parameter called "openid.response_nonce" which contains a string, you should be able to refer to it with:
//following not tested, and not checked for syntax errors
private Map openid = new HashMap();
//In Constructor{
oauth.put("response_nonce","");
}
//create BOTH a getter and setter for openid
public getOpenid(){
return openid;
}
public setOpenid(Map openid){
this.openid = openid;
}
Now struts2 should be able to figure out how to set the value... I think, sorry didn't test it. You could always create a class called Openid with a response_nonce property(along with the appropriate getters and setters for that Class)... but I think in this case it might be best to just use RequestAware if you only need that single property.
I think that you maybe looking for the Alias interceptor. http://struts.apache.org/2.0.14/docs/alias-interceptor.html
Regards
I'm writing some unit tests to assert that all our controller action methods are marked with proper custom attributes, but I don't really know what the criteria is for determining whether a public method can act as MVC action or not.
I would assume that a criteria could be the return value type (it has to be ActionResult or a derivative). Is this true? What about static methods?
For a method to be considered an action, it has to meet the following criteria:
It must be public and not static
It must not have a "special" name in order to exclude constructors, events etc.
It must not be defined on System.Web.Mvc.Controller or any other base class in order to exclude .ToString() and family.
Generic methods will throw an exception, yet for some reason they are considered actions. As for the return type, it does not necessarily have to be an ActionResult, since you can return e.g. a string for text data.
I beleive all public methods in a controller are treated as actions - even one returning a string.
Determining the true list of actions on a controller is a tricky problem. The only correct answer is that it "depends"! The list that Saulius gave is pretty much correct - if you're using the default ControllerActionInvoker - which of course, most people use.
If you want to avoid duplicating the logic I would recommend using the ControllerActionInvoker itself to get the list of actions and then verify the contents of the list that it returns.
You'll have to write a class that derives from ControllerActionInvoker so that you can call the GetControllerDescriptor() method. The return value of that method is a ControllerDescriptor, which is an abstract descriptor of what the controller has. You can then call GetCanonicalActions(), which returns a list of ActionDescriptors. Each of those items represents what is typically and action method.
To hook it all up you'll need to:
Instantiate your controller
Set its ActionInvoker property to be an instance of your custom invoker
Create a ControllerContext instance that has its Controller instance set to your controller
Call a new public method on your invoker that in turn calls GetControllerDescriptor()
Then verify the results and you're done!
Of course, I haven't tried any of this but in theory it all works :)