How do I pass parameters between request-scoped beans - spring

This is a question that has been bothering me for sometime. My application uses ICEFaces for our UI framework and Spring 2.5 for Dependency Injection. In addition, Spring actually maintains all of our backing beans, not the ICEFaces framework, so our faces-config is basically empty.
Navigation is not even really handled through navigation-rules. We perform manual redirects to new windows using window.open.
All of our beans are defined in our appContext file as being request-scoped. I have Page ABC which is backed by BackingBeanABC. Inside that backing bean, I have a parameter say:
private Order order;
I then have Page XYZ backed by BackingBeanXYZ. When I redirect from page ABC to page XYZ, I want to transfer the 'order' property from ABC to XYZ. The problem is since everything is request-scoped and I'm performing a redirect, I am losing the value of 'description'.
There has got to be an easier way to pass objects between beans in request scope during a redirect. Can anyone assist with this issue?

Session scope solves your issue.
You can read more about it in Spring's reference documentation.
Another alternative is to set the order object directly on the HttpSession object. I would have prefered that and only have your services, controllers and repositories managed by Spring.

Create a single session scoped bean that the request scoped beans can reference via the FacesContext.

Related

Accessing to session objects from facelets

we are working on a customer platform project and we have some doubts about the session objects and the best way to access them.
In order, it may be:
Login from client
SessionScopped bean gets fired with the template render.
Diferent pages (facelets) with ViewScoped or RequestScoped bean to navigate to sections.
We are injecting the sessionscoped bean to the rest of the beans when needed, so we have the same properties everywhere.
The doubt is, in the diferent facelets of sections, how we should access to the session objects? i mean
#{requestscopedbean.sessionscopedbean.object}
or should be directly calling to the session bean like:
#{sessionscopedbean.object}
We use PrimeFaces 6.2, I guess it is not the point. Just in case. And we are running all this on a javaee-5 compatible server

How to set few parameter in the session of a jsf/primefaces application [duplicate]

I noticed that there are different bean scopes like:
#RequestScoped
#ViewScoped
#FlowScoped
#SessionScoped
#ApplicationScoped
What is the purpose of each? How do I choose a proper scope for my bean?
Introduction
It represents the scope (the lifetime) of the bean. This is easier to understand if you are familiar with "under the covers" working of a basic servlet web application: How do servlets work? Instantiation, sessions, shared variables and multithreading.
#Request/View/Flow/Session/ApplicationScoped
A #RequestScoped bean lives as long as a single HTTP request-response cycle (note that an Ajax request counts as a single HTTP request too). A #ViewScoped bean lives as long as you're interacting with the same JSF view by postbacks which call action methods returning null/void without any navigation/redirect. A #FlowScoped bean lives as long as you're navigating through the specified collection of views registered in the flow configuration file. A #SessionScoped bean lives as long as the established HTTP session. An #ApplicationScoped bean lives as long as the web application runs. Note that the CDI #Model is basically a stereotype for #Named #RequestScoped, so same rules apply.
Which scope to choose depends solely on the data (the state) the bean holds and represents. Use #RequestScoped for simple and non-ajax forms/presentations. Use #ViewScoped for rich ajax-enabled dynamic views (ajaxbased validation, rendering, dialogs, etc). Use #FlowScoped for the "wizard" ("questionnaire") pattern of collecting input data spread over multiple pages. Use #SessionScoped for client specific data, such as the logged-in user and user preferences (language, etc). Use #ApplicationScoped for application wide data/constants, such as dropdown lists which are the same for everyone, or managed beans without any instance variables and having only methods.
Abusing an #ApplicationScoped bean for session/view/request scoped data would make it to be shared among all users, so anyone else can see each other's data which is just plain wrong. Abusing a #SessionScoped bean for view/request scoped data would make it to be shared among all tabs/windows in a single browser session, so the enduser may experience inconsitenties when interacting with every view after switching between tabs which is bad for user experience. Abusing a #RequestScoped bean for view scoped data would make view scoped data to be reinitialized to default on every single (ajax) postback, causing possibly non-working forms (see also points 4 and 5 here). Abusing a #ViewScoped bean for request, session or application scoped data, and abusing a #SessionScoped bean for application scoped data doesn't affect the client, but it unnecessarily occupies server memory and is plain inefficient.
Note that the scope should rather not be chosen based on performance implications, unless you really have a low memory footprint and want to go completely stateless; you'd need to use exclusively #RequestScoped beans and fiddle with request parameters to maintain the client's state. Also note that when you have a single JSF page with differently scoped data, then it's perfectly valid to put them in separate backing beans in a scope matching the data's scope. The beans can just access each other via #ManagedProperty in case of JSF managed beans or #Inject in case of CDI managed beans.
See also:
Difference between View and Request scope in managed beans
Advantages of using JSF Faces Flow instead of the normal navigation system
Communication in JSF2 - Managed bean scopes
#CustomScoped/NoneScoped/Dependent
It's not mentioned in your question, but (legacy) JSF also supports #CustomScoped and #NoneScoped, which are rarely used in real world. The #CustomScoped must refer a custom Map<K, Bean> implementation in some broader scope which has overridden Map#put() and/or Map#get() in order to have more fine grained control over bean creation and/or destroy.
The JSF #NoneScoped and CDI #Dependent basically lives as long as a single EL-evaluation on the bean. Imagine a login form with two input fields referring a bean property and a command button referring a bean action, thus with in total three EL expressions, then effectively three instances will be created. One with the username set, one with the password set and one on which the action is invoked. You normally want to use this scope only on beans which should live as long as the bean where it's being injected. So if a #NoneScoped or #Dependent is injected in a #SessionScoped, then it will live as long as the #SessionScoped bean.
See also:
Expire specific managed bean instance after time interval
what is none scope bean and when to use it?
What is the default Managed Bean Scope in a JSF 2 application?
Flash scope
As last, JSF also supports the flash scope. It is backed by a short living cookie which is associated with a data entry in the session scope. Before the redirect, a cookie will be set on the HTTP response with a value which is uniquely associated with the data entry in the session scope. After the redirect, the presence of the flash scope cookie will be checked and the data entry associated with the cookie will be removed from the session scope and be put in the request scope of the redirected request. Finally the cookie will be removed from the HTTP response. This way the redirected request has access to request scoped data which was been prepared in the initial request.
This is actually not available as a managed bean scope, i.e. there's no such thing as #FlashScoped. The flash scope is only available as a map via ExternalContext#getFlash() in managed beans and #{flash} in EL.
See also:
How to show faces message in the redirected page
Pass an object between #ViewScoped beans without using GET params
CDI missing #ViewScoped and #FlashScoped
Since JSF 2.3 all the bean scopes defined in package javax.faces.bean package have been deprecated to align the scopes with CDI. Moreover they're only applicable if your bean is using #ManagedBean annotation. If you are using JSF versions below 2.3 refer to the legacy answer at the end.
From JSF 2.3 here are scopes that can be used on JSF Backing Beans:
1. #javax.enterprise.context.ApplicationScoped: The application scope persists for the entire duration of the web application. That scope is shared among all requests and all sessions. This is useful when you have data for whole application.
2. #javax.enterprise.context.SessionScoped: The session scope persists from the time that a session is established until session termination. The session context is shared between all requests that occur in the same HTTP session. This is useful when you wont to save data for a specific client for a particular session.
3. #javax.enterprise.context.ConversationScoped: The conversation scope persists as log as the bean lives. The scope provides 2 methods: Conversation.begin() and Conversation.end(). These methods should called explicitly, either to start or end the life of a bean.
4. #javax.enterprise.context.RequestScoped: The request scope is short-lived. It starts when an HTTP request is submitted and ends after the response is sent back to the client. If you place a managed bean into request scope, a new instance is created with each request. It is worth considering request scope if you are concerned about the cost of session scope storage.
5. #javax.faces.flow.FlowScoped: The Flow scope persists as long as the Flow lives. A flow may be defined as a contained set of pages (or views) that define a unit of work. Flow scoped been is active as long as user navigates with in the Flow.
6. #javax.faces.view.ViewScoped: A bean in view scope persists while the same JSF page is redisplayed. As soon as the user navigates to a different page, the bean goes out of scope.
The following legacy answer applies JSF version before 2.3
As of JSF 2.x there are 4 Bean Scopes:
#SessionScoped
#RequestScoped
#ApplicationScoped
#ViewScoped
Session Scope: The session scope persists from the time that a session is established until session termination. A session terminates
if the web application invokes the invalidate method on the
HttpSession object, or if it times out.
RequestScope: The request scope is short-lived. It starts when an HTTP request is submitted and ends after the response is sent back
to the client. If you place a managed bean into request scope, a new
instance is created with each request. It is worth considering request
scope if you are concerned about the cost of session scope storage.
ApplicationScope: The application scope persists for the entire duration of the web application. That scope is shared among all
requests and all sessions. You place managed beans into the
application scope if a single bean should be shared among all
instances of a web application. The bean is constructed when it is
first requested by any user of the application, and it stays alive
until the web application is removed from the application server.
ViewScope: View scope was added in JSF 2.0. A bean in view scope persists while the same JSF page is redisplayed. (The JSF
specification uses the term view for a JSF page.) As soon as the user
navigates to a different page, the bean goes out of scope.
Choose the scope you based on your requirement.
Source: Core Java Server Faces 3rd Edition by David Geary & Cay Horstmann [Page no. 51 - 54]

How do you pass parameters and navigate to Spring managed bean with custom scope - view?

I would like to give you some context first.
The Context
I am currently developing a web application using Spring framework, where I would like to provide users with displaying/editing different instances of the same entity type of model in separate tabs. For displaying and retrieving attributes of these entities, I am using Spring managed beans with matching Data Transfer Object instances and with #Autowired annotated instances of service layer interface implementations for persisting the data.
Because I have experienced, that Spring's session scoped beans are not suitable for multi-tab editing and request scoped beans cannot hold the submitted data "long enough" for redisplay, I have implemented a "custom" scoped view beans. That seems to work fine for displaying and editing multiple same type pages (and entities on them) and for holding the data as long as the bean's action methods return void/null.
Navigating between pages is currently done by the String type return value of the destination page on the bean action methods send to the components like h:commandLink and h:commandButton to be resolved by JSF or by using simple html links.
The Problem
How do you navigate with one h:link/h:button to another page and ALSO pass it parameters to display by a Spring view scope bean after page landing?
Is there a way, how to redirect to another page at first -- for example from a page with list of system users, and then displaying details of a user passed from the launching page?
Questions to be answered and possible solutions?
If I have understood and implemented it correctly, they are already managed and injected with Spring, so they cannot work exactly as JSF's ViewScoped beans, so I cannot easily use their attributes annotated as JSF managed and pass them values of parameters for displaying them on a details/edit page AFTER navigating to it. When I try it, it results in a "CDI #ViewScoped bean functionality unavailable" error message. I think, that for the same reason using #ManagedBean annotated JSF beans and it's f:viewParam on destination page did not work. Is that correct?
I have tried passing parameter to Spring view scoped bean's function with return value of a destination page, but obviously(?) the bean gets recreated after landing on it with it's parameters emptied. Trying to define navigation rule for a Spring view scoped bean's action with the void return type and a landing page name also did not work. It seems like the Spring bean was not recognised in faces-config.xml. Is it so?
Should I use some longer-lived Spring bean's method for calling the view scoped one's constructor with the right parameters? But how do I prevent the view scoped bean's recreation after redirecting?
Switching from view scope to session scope would solve my problem, but it would result in a bad user experience as I see it and given, how my application should work with multiple tabs of the same type instances for the same user.
Passing and retrieving the secured parameters by a view scoped bean from the url address seems to me as maybe not the best security practice. But I am also using Spring Security roles in UI, service layer and url intercept as well as AOP on my service methods for checking the owner of retrieved data. Would be using some data identifier in the url be the only solution possibly working? Is it a worse/better solution from the point of security than using session scoped beans?
I welcome and thank you for every advice you could give me, because this is my first Spring pet project and I am learning on the way.

Spring MVC controller initialization code

I have a spring MVC project, in one of the controllers, i have a DB connection object that needs to be initialized only once in the controller, what is the best approach to follow when adding this initialization code, for now, i used a static block in the controller where i added the initialization code, do u have any other suggestions.
thanks in advance
Make it a Spring bean. That way it's a singleton (by default), and can be injected wherever you want.
Note that even if you leave its initialization in the controller, making it static is useless, since a controller is also a Spring bean, which is a singleton by default.
Well in spring you don't need to initialize the db connections yourself , It provide support for db connections
You just need to specify the the bean in .xml files and directly autowired that bean into your controller
use dao pattern to implement database connections see some example it will be easy container will manage db connections object life cycle for you
Thanks,
Himanshu
May I recommend you read the Spring reference guide for Object Relational Mapping and Data Access? Its quite comprehensive and details how to set up a data source, session factory, implement DAO classes, transaction management etc... Hopefully you will find this is a good place to start.

Real use case of proptotype scope of spring beans

Waht is a real example for such kind of stuff? I have already looked through this post, but the answers to this post seem inconclusive to me. Also there is an advice: "As a rule, use the prototype scope for all stateful beans and the singleton scope for stateless beans" - from spring reference, but why do we need our services to be stateful? We can just share this state as a simple dto among services' calls.
One popular use of it is to associate separate instance of a bean to each HTTP session.
Consider your have a bean class called UserConfig. You can set this bean with prototype scope, and configure such that each new HTTP session has its own UserConfig bean instance. (Spring MVC has its own scope called "session" for this purpose, but the concept is similar)
Also the user can change your site configuration, and the changed state is saved on its own instance of the bean (as opposed of altering the global single instance if you set it into singleton scope)

Resources