Is the ValueStack life cycle across the application in struts2? - struts2

I can set a property on ValueStack in several ways.
ValueStack stack = ActionContext.getContext().getValueStack();
stack.getContext().put("resultDTO",resultDTO); //1. creates a different branch
//parallel to root
stack.set("resultDTO", resultDTO); //2. pushes on root as a Map?
stack.push(resultDTO); //3. pushes on root
myActionClass.setProperty(); //4. normal action accessor
I need to be able to get all these values back in JSP, freemarker and java like
stack.findValue() or stack.findString().
I want to know about the life cycle of each of these 4 setting methods. Is it across application. Is the ValueStack created every request and the application and session values are set in it for every request?
I know the 4th method is the most common approach but i may not be using that in all places, where action class is not easily accessible.
I have another doubt about accessing in JSP
<s:push value="resultDTO" ><s:property value="data.form1[0]" /></s:push>
<!--5.works for context.put() & stack.set() both-->
<s:property value="#resultDTO.data.form1[0].countryofissue" /> <!--6.context.put()-->
<s:property value="resultDTO.data.form1[0].countryofissue" /> <!--7.stack.set()-->
<s:property value="data.form1[0].countryofissue" /> <!--8.stack.push()-->
I also want to know how 5th point works in both stack.getContex().put() and stack.set()? I understand that in 6th the resultDTO I am accessing, is a different root and in 7th, it's the child of default root, which is ValueStack. In 8th it starts to search from default root.
I went through http://struts.apache.org/2.0.11.1/docs/ognl.html, http://struts.apache.org/2.1.2/struts2-core/apidocs/com/opensymphony/xwork2/util/ValueStack.html and rather confusing this link http://www.opensymphony.com/ognl/html/DeveloperGuide/introduction.html#embeddingOGNL
Having said all these I am little inclined to using stack.getContext().put() method as I can clearly see the values in by setting the url as ?debug=browser. Advise me if I am going wrong.

The ValueStack is per-request. If you place values on the stack, they are accessible later in the request (i.e., in the view layer), but would not survive a redirect, which would be a new HTTP request and have its own ValueStack.
Under normal conditions, parameters in the URL or in a form post would be set on the action using the action's setter methods. In an interceptor, you can add values directly to the stack. For example, the ExceptionMappingInterceptor uses the stack.push(Object) method to publish exceptions for use on error pages.
stack.getContext().put(String, Object) -- Places the key/value into a map that lives on the stack. The map represents the context of the stack.
stack.set(String, Object) -- Places the key/value into a map that lives on the stack. I'm not sure how this relates to the previous method, other than it is a different map.
stack.push(Object) -- This places the object on the root of the stack.
You shouldn't need to place anything on the stack from within the view layer, so I'm curious what you are trying to do that necessitates that.

Related

ASP.NET Core MVC - Complex Objects specific to a Controller

I'm sort of learning on the fly (coming from a desktop perspective), so forgive me if this seems dumb.
This would be a CRUD type of application, so imagine if you have two controllers for data entry:
SupervisorController
EmployeeController
Now, let's say the User goes to https://whatever/SupervisorController and before I do anything, I need to create some objects specific to the Supervisor screen (e.g. I create an Access object, which reads some data from a source, which tells me what they have access to on that specific Supervisor screen).
OK, in my Index method I construct that object and pass it to my view. But, that object won't persist when say, another method for that controller is called, or say Refresh on the browser is clicked (the constructor for the controller is called each time).
And let's say that the user goes to the browser and types https://whatever/SupervisorController/AnotherMethod themselves. Well, I only constructed that object in my Index Method. So now I have to construct that same object, again, there? And pass it to this view?
Where I'm getting at is that if someone goes to any method of the SupervisorController, if the object isn't there, I want to construct some "supervisor" specific objects, keep them available in my "private member variables", until I'm done with SupervisorController. Meaning, if they move on to say EmployeeController, those objects can now go away.
At EmployeeController, I'll want something similar. Complex objects created specifically for Employee CRUD, that I won't need once I'm done with Employees.
I mean, I really don't want to create these objects and store them in the Session for the lifetime of the session, as they are really only needed for their specific controllers. On top of that, how much data do I really want to be storing in session memory before it gets to be too much!
But if I don't store them somewhere, I would have to re-create these objects for every action/method. I don't want to create them in every method of a specific controller (I could be going to a database to get some specific information). For example, I'm playing around with a Grid Control on my Index page, and when you reach that page, there's the initial call to the Index method, and then the grid itself makes a call to this Read method I have. So I would be creating that object twice!? On one call to https://whatever/SupervisorController?
How do people handle what I'm trying to achieve? Or is there some way I need to look at it now, and implement it to those guidelines?

Groovy: Are two variables referring to the same object?

I am debugging some Groovy code for a website and have hit an issue where I create an object A in controller in one part of the flow and set a variable within it (read it back and its correct).
I then pick up what I had understood to the the same object in a different controller. But the variable is no longer set.
Either my assumption that the object A in the first controller is the same object A as picked up the the second controller is wrong or something has modified the value en-route.
So, what might be a very basic question (and I have have a horrible feeling that it points to some fundamental misunderstanding on my part of how Groovy/Java works - so please be gentle) :
How can I tell if the object A in controller 1 is the same as the object A in controller 2 (by the same I mean point to the same object, not that they are equivalent).
I then pick up what I had understood to the the same object in a
different controller.
If you show an example of what you are doing in the first controller and what you are doing in the second controller that would help clarify what is going on. It isn't clear what you might mean by "pick up" in the sentence quoted above.
If you can orchestrate things such that you have the 2 references at the same time you can call o1.is(o2) which will tell you if o1 points to the same object as o2. Something you can use to help debug the situation is in the first controller your can call System.identityHashCode(o1) and in the second controller you can call System.identityHashCode(o2) and see if those return the same value.
There are times in a web app where the notion of being the same object can be ambiguous. For example, if you have 2 separate proxies but they are proxying the same instance, there are contexts where you would treat them as the same object. Another example is that if you are dealing with persistent entities you could have 2 separate instances in memory that actually correspond to the same record in the data store.
Anyway, the identityHashCode approach mentioned above is a technique you could use to know if these objects are the same object or not. If that doesn't do it for you and you can show some code or provide some more details that might help.
If you want to make some variables available in several controllers, you can do it in one of the following ways:
put the object in a session
put the object in a flash scope
put the object in a flow scope - here you MUST make sure, that you are accessing the SAME flow.
use a singleton service to persist the value permanently or temporarily
use a static field somewhere (shall never be used though)

Passing parameters between Request Scoped Managed Beans in JSF + EJB 3.1

Our problem is a very basic, simple implementation of editing the database using JSF + EJB.
Keeping things short:
two separate XHTML views, use two separate Managed Beans #RequestScope.
WebuserListBean and EditWebuserBean, and with #ManagedProperty we inject WebuserListBean, so we could obtain selected user data. So far no problems. Views are filled with data succesfully!
BUT!
We want to be able to edit the user!
And here (to my surprise) we cannot overcome the problem.
1st try:
Because the request scoped bean is dead after filling the view, on Save() method the #PostConstruct tries to launch again, of course it can't. So we couldn't even obtain it from database or anything.
2nd try:
Because the request scoped bean is dead after filling the view, if we do not set up user as field in #postconstruct, we lose our connection with user object which was linked on previous view (and injected, but now that view is dead too).
3rd try:
Cannot inject RequestScope in ViewScoped
Ok and our restrictions, because we think it's wrong way:
We dont want to create a SessionScoped Managed Bean for this
We dont want to use any params etc. We want to use EJB
We are not sure if we could store data in Stateful session bean which is our
endpoint for the module? Is it proper approach?
Thanks for any advice, we could paste some code but i guess it is pointless!
Cheers!
There are many ways to do it, but I recommend using the flash if the pages involved in the navigation are in the same folder (I recently found out reading a BalusC answer that there is a known issue with the flash, in which it will not hold values when navigating between pages in different folders!).
The flash is a way to hold parameters for a little longer than the context of a single request (concept taken from Ruby if I'm not mistaken, someone correct me if I'm wrong), allowing for the sent parameters to be fetched in a subsequent view, for example. Those values are discarded in the second request issued after saving them, if I'm not mistaken. You can inject the flash in your managed beans like this:
#ManagedProperty("#{flash}")
private Flash flash;
public void setFlash(Flash newFlash) {
flash = newFlash;
}
Then, you access it like a map with the put and get methods. If you use the put method in a bean, return a redirection rule and, on the second bean, use the get method your object should be there.
You can also find a highly comprehensible guide of communication in JSF (listing a really extensive list of options) here, in particular if you need to navigate between pages in different folders.

Struts 2 how to reference a value with dynamic name on the valuestack

Say there is a value in valuestack of struts 2; when we code the jsp, we don't know what the exact variable name of this value, but we only know that the variable name of this value is saved in another variable name, say "XXX".
The question is how can get the value by using "XXX", I try this, but it is not working.
<s:property value="${XXX}"/>
The action marshals data for the view, as such it should do the processing to get the required data. From the sounds of it, it sounds like the action could gather the appropriate data into a map.
However there are strange cases and you might have one. But before addressing that if you only have the name of the variable where can it be assumed the real variable is? Is it in the value stack (and if so what is stopping you from accessing it directly)? If it is not on the value stack you'll need to enable static method assess and create an appropriate static method, since you are only provided with the name of the variable and assuming it is a property of a java bean you'll then need to use reflection or apache beanutils.
In general it is better to get what you need in the action for your views.
Also to set a value in your jsp's you are aware of the struts2 set tag (this is probably not what you want but there was a small chance it was so I included it)? See: http://struts.apache.org/2.2.3.1/docs/set.html

What is a preferred way of displaying result as a table?

I have an action that populates the result from the DB. Right now, I see a way of doing it and that is to make the Action ServletRequestAware, set the populated list as a request attribute and show it in jsp.
Since a lot of improvements have been introduced into struts2, is there any other way of doing that? The first thing that comes to my mind is to use displayTag and change the return type of Action to a List, but that does not seem to work.
Thanks for any replies in advance.
You question is unclear, you should read some book about Struts2 to get the general idea.
No need to make the Action ServletRequestAware. The mapping from http parameters to actions fields is automatically done via the Param interceptor (already set in the default configuration). And one of the points of Struts2 is decoupling the action from the http protocol, you should not (typically) do anything related to http in your action.
Tipically, in your action execute() method (or whatever) you'll get the data to display from the DB and set it as one property of your action, so that is accesable from some getter.
Then, in your view page (JSP or whatever) you'll display it. You can use displayTag, but first you'll prefer to display it "manually", to understand what's involved. See for example here http://www.roseindia.net/struts/struts2/struts2controltags/iterator-tag.shtml
For manually displaying a table, also see this example http://www.vaannila.com/struts-2/struts-2-example/struts-2-crud-example-1.html , search for the <table class="userTable> tag.

Resources