Is it possible to maintain Application Scope in Spring Webflow? - scope

I have a significant logic which applies to all the users using the application. Using conversion scope I was able to maintain the data but when it comes to performance, each time user loads the logic taking almost 50% of CPU Usage. So, I am thinking to load the logic on application startup and keep the data on application scope so that all users Conversations have access to it ?
Any suggestions or ideas or referrals are highly appreciated, thanks in advance.

Webflow can access all of your spring beans. If you have Spring manage bean that can return the data, then you can access it from your flow definition. Webflow uses the bean name when resolving the bean.
In the below snippet, we call the Spring managed bean multiFactorManager and store the result in a flow scoped variable.
<on-entry>
<evaluate
expression="multiFactorManager.getMultiFactorSettings(account)"
result="flowScope.multiFactorSettings" />
</on-entry>

Related

Thread-safety of #FlowScoped beans

I have done a small experiment with #FlowScoped beans, whose purpose, as I understand, is to make easier creating "wizard-type" web applications, gradually accumulating data over a sequence of pages, then, once all the data is ready, writing it to the persistent storage (this is just an example, nothing prevents of course to write to the persistent storage during intermediate steps). As I saw, the calls to a #FlowScoped bean are not synchronized, and thus there is in principle the possibility of corrupting the data stored in the bean (by doing a double submit, or launching by any other means two almost simultaneous HTTP requests, which invoke the methods of the bean). This unlike #ConversationScoped beans the calls to which are synchronized.
What puzzles me is that about #SessionScoped beans I have found several links which speak about the need to synchronize the access to a #SessionScoped bean (or recommending not to use them at all, apart from user data which changes rarely), but I have not found anything like that about #FlowScoped beans.
What is considered then to be a "best practice" for using #FlowScoped beans? Am I missing something?
EDIT
#FlowScoped seems, at least to me, to be motivated in part by Spring WebFlow, with which I have some experience, and which, as I know, offers integration with JSF 2 (not all JSF 2.2 features seem to be implemented, but it seems that PrimeFaces is usable, for example). I know that Spring WebFlow + JSF is actually used in "real world" applications, and the issue of thread safety of flow scoped objects is handled there elegantly together with double submit issues (flow execution id must be supplied with each HTTP request, and it expires and a new one is returned after a HTTP request which invokes a Spring WebFlow "action" method: therefore one cannot invoke concurrently more than one "action" method for the same user and flow id).
So I want to understand, what is the best practice in the case of JSF 2.2 if I wish to use the #FlowScoped beans to construct an application "flow" (without using Spring WebFlow). Do I really need to synchronize the access to #FlowScoped beans myself, or there is some standard way to deal with such issues?

Does JSF manage access authorization for #ManagedBean methods?

I have a #ManagedBean #SessionScoped class to represent a user session. Assume it has a theoretical method doHorribleThings(). Access to methods of this bean through JSF can, for example, be enabled through Expression Language attributes such as action="#{userSession.doHorribleThings()}" on a Prime Faces p:commandButton.
My question is, does JSF manage access security for such method? Can a user issue performing the action of a button that is not being rendered for him, e.g. by sending an artificial HTTP package? Or does JSF capsulate a virtual client desktop that stretches accross the network, effectively enabling access control through GUI design?
No, JSF doesn't have an access security for invoking a method in a managedbean other than the UI, as far as I know.
Because if your able to mimic an action that happens through the click of a JSP/Primefaces button with a manual HTTP request then JSF container cannot identify the difference between the two and hence work the same way for both the request

Jsf: what bean scope for a two page master-detail?

In a jsf application I have a table with summarized data. If I'm interested in the details I can click on a row an see the details in another page.
If the managed bean of the 'master' page is ion view scope it is re-created every time I return back from the 'detail' page and I don't think it is a good idea if the user is supposed to check the details more times. I can solve putting the bean in sessions cope but this way the bean (and the data) are kept in memory also when the user is interacting with the application in a completely different section. Probably I would need a custom scope but:
the documentation about custom scope is poor and I'm a bit frightened about people complaining it has bugs and doesn't work well.
the scenario I'm dealing with seems to me quite general, so I wonder why there is no ready solution for it.
Thanks
Filippo
If the detail page has to be idempotent (i.e. it's permalinkable, bookmarkable, searchbot-crawlable), just use two request or view scoped beans and use a GET link with the entity ID as request parameter to go from master page to detail page. See also Creating master-detail pages for entities, how to link them and which bean scope to choose for a concrete example.
If the detail page does not need to be idempotent, then you can always conditionally render the master and detail in the very same view or even display the detail in some modal dialog from the master page on. This way you can continue with a single view scoped bean.
In JSF side you must not be too much worried about the DB performance cost. Rather configure and finetune it in the persistence layer. In JPA for example you can setup a second level cache. If you've much more than 500~1000 items, then consider database-level pagination.
It may be valid to reload the master page each time e.g. if the data could have changed after viewing the details page. However, if you want to keep the data available for longer than #ViewScoped your options are:
You should be using JEE6 of which JSF 2.0 is a part of, so look at Conversation Scope (part of CDI)
Some additional scopes for JEE6 CDI is available through the MyFaces CODI
Potentially use Session Scope and make sure you tidy up when a Request hits which is not for the Master or Details page
Rework your design to use Ajax, so if clicking a record on the Master page its details load in the same view. You could then use #ViewScoped
My preference would be to look at the Conversation Scope. You don't mention which JSF implementation you are running or in which environment.

Why shouldn't I use a JSF SessionScoped bean for logic?

I'm developing a java EE web app using JSF with a shopping cart style process, so I want to collect user input over a number of pages and then do something with it.
I was thinking to use an EJB 3 stateful session bean for this, but my research leads me to believe that a SFSB is not tied to a client's http session, so I would have to manually keep track of it via an httpSession, some side questions here . . .
1) Why is it called a session bean, as far as I can see it has nothing to do with a session, I could achieve the same by storing a pojo in a session.
2) What's the point of being able to inject it, if all I'm gonna be injecting' is a new instance of this SFSB then I might as well use a pojo?
So back to the main issue I see written all over that JSF is a presentation technology, so it should not be used for logic, but it seems the perfect option for collecting user input.
I can set a JSF session scoped bean as a managed property of all of my request beans which means it's injected into them, but unlike a SFSB the JSF managed session scoped bean is tied to the http session and so the same instance is always injected as long as the http session hasn't been invalidated.
So I have multiple tiers
1st tier) JSF managed request scoped beans that deal with presentation, 1 per page.
2nd tier) A JSF managed session scoped bean that has values set in it by the request beans.
3rd tier) A stateless session EJB who executes logic on the data in the JSF session scoped bean.
Why is this so bad?
Alternative option is to use a SFSB but then I have to inject it in my initial request bean and then store it in the http session and grab it back in each subsequent request bean - just seems messy.
Or I could just store everything in the session but this isn't ideal since it involves the use of literal keys and casting . etc .. etc which is error prone. . . and messy!
Any thoughts appreciated I feel like I'm fighting this technology rather than working with it.
Thanks
Why is it called a session bean, as far as I can see it has nothing to do with a session, I could achieve the same by storing a pojo in a session.
From the old J2EE 1.3 tutorial:
What Is a Session Bean?
A session bean represents a single
client inside the J2EE server. To
access an application that is deployed
on the server, the client invokes the
session bean's methods. The session
bean performs work for its client,
shielding the client from complexity
by executing business tasks inside the
server.
As its name suggests, a session bean
is similar to an interactive session.
A session bean is not shared--it may
have just one client, in the same way
that an interactive session may have
just one user. Like an interactive
session, a session bean is not
persistent. (That is, its data is not
saved to a database.) When the client
terminates, its session bean appears
to terminate and is no longer
associated with the client.
So it has to do with a "session". But session not necessarily means "HTTP session"
What's the point of being able to inject it, if all I'm gonna be injecting' is a new instance of this SFSB then I might as well use a pojo?
Well, first of all, you don't inject a SFSB in stateless component (injection in another SFSB would be ok), you have to do a lookup. Secondly, choosing between HTTP session and SFSB really depends on your application and your needs. From a pure theoretical point of view, the HTTP session should be used for presentation logic state (e.g. where you are in your multi page form) while the SFSB should be used for business logic state. This is nicely explained in the "old" HttpSession v.s. Stateful session beans thread on TSS which also has a nice example where SFSB would make sense:
You may want to use a stateful session
bean to track the state of a
particular transaction. i.e some one
buying a railway ticket.
The web Session tracks the state of
where the user is in the html page
flow. However, if the user then gained
access to the system through a
different channel e.g a wap phone, or
through a call centre you would still
want to know the state of the ticket
buying transaction.
But SFSB are not simple and if you don't have needs justifying their use, my practical advice would be to stick with the HTTP session (especially if all this is new to you). Just in case, see:
Stateless and Stateful Enterprise Java Beans
Stateful EJBs in web application?
So back to the main issue I see written all over that JSF is a presentation technology, so it should not be used for logic, but it seems the perfect option for collecting user input.
That's not business logic, that's presentation logic.
So I have multiple tiers (...)
No. You have probably a client tier, a presentation tier, a business tier, a data tier. What you're describing looks more like layers (not even sure). See:
Can anybody explain these words: Presentation Tier, Business Tier, Integration Tier in java EE with example?
Spring, Hibernate, Java EE in the 3 Tier architecture
Why is this so bad?
I don't know, I don't know what you're talking about :) But you should probably just gather the multi page form information into a SessionScoped bean and call a Stateless Session Bean (SLSB) at the end of the process.
1) Why is it called a session bean, as far as I can see it has nothing to do with a session, I could achieve the same by storing a pojo in a session.
Correction: an EJB session has nothing to do with a HTTP session. In EJB, roughly said, the client is the servlet container and the server is the EJB container (both running in a web/application server). In HTTP, the client is the webbrowser and the server is the web/application server.
Does it make more sense now?
2) What's the point of being able to inject it, if all I'm gonna be injecting' is a new instance of this SFSB then I might as well use a pojo?
Use EJB for transactional business tasks. Use a session scoped managed bean to store HTTP session specific data. Neither of both are POJO's by the way. Just Javabeans.
Why shouldn't I use a JSF SessionScoped bean for logic?
If you aren't taking benefit of transactional business tasks and the abstraction EJB provides around it, then just doing it in a simple JSF managed bean is indeed not a bad alternative. That's also the normal approach in basic JSF applications. The actions are however usually to be taken place in a request scoped managed bean wherein the session scoped one is been injected as a #ManagedProperty.
But since you're already using EJB, I'd question if there wasn't a specific reason for using EJB. If that's the business requirement from upper hand, then I'd just stick to it. At least, your session-confusion should now be cleared up.
Just in case you're not aware of this, and as a small contribution to the answers you have, you could indeed anotate a SFSB with #SessionScoped, and CDI will handle the life cycle of the EJB... This would tie an EJB to the Http Session that CDI manages. Just letting you know, because in your question you say:
but my research leads me to believe that a SFSB is not tied to a client's http session, so I would have to manually keep track of it via an httpSession, some side questions here . . .
Also, you could do what you suggest, but it depends on your requirements, until CDI beans get declarative transaction support or extended persistence contexts etc, you'll find yourself writing a lot of boilerplate code that would make your bean less clean. Of course you can also use frameworks like Seam (now moving to DeltaSpike) to enhance certain capabilities of your beans through their extensions.
So I'd say yes, at first glance you may feel it's not necessary to use a stateful EJB, but certain use cases may be better solve through them. If a user adds a product to his cart, and another user adds this same product later, but there is only one unit in stock, who gets it? the one who does the checkout faster? or the one who added it first? What if you want to access your entity manager to persist a kart in case the user decides to randomly close his browser or what if you have transactions that spawn multiple pages and you want every step to be synchronized to the db? (To keep a transaction open for so long is not advisable but maybe there could be a scenario where this is needed?) You could use SLSB but sometimes it's better and cleaner to use a SFSB..

Calling a SLSB with Seam security from a servlet

I have an existing application written in SEAM that uses SEAM Security (http://docs.jboss.org/seam/2.1.1.GA/reference/en-US/html/security.html). In a stateless EJB, I might find something like this:
#In
Identity identity;
...
if(identity.hasRole("admin"))
throw new AuthException();
As far as I understand, Seam injects the Identity object from the SessionContext of the servlet that invokes the EJB (this happens "behind the scenes", since Seam doesn't really use servlets) and removes it after the call. Is this correct?
Is it now possible to access this EJB from another servlet (in this case, that servlet is the server side of a GWT application)? Do I have to "inject" the correct Identity instance? If I don't do anything, Seam injects an instance, but doesn't correctly correlate the sessions and instances of Identity (so the instances of Identity are shared between sessions and sometimes calls get new instances etc.).
Any help and pointers are very welcome - thanks!
Technology: EJB3, Seam 2.1.2. The servlets are actually the server-side of a GWT app, although I don't think this matters much. I'm using JBoss 5.
Seam injects the Identity object from the SessionContext of the servlet that invokes the EJB and removes it after the call. Is this correct ?
Yes, but do not forget you must enable EJB Seam interceptor See here how to
...
Is it now possible to access ANY EJB from another servlet
Yes, you can use its Global JNDI (Vendor dependent) to retrieve it. See here how you can set up and retrieve your EJB #State less / ful bean. If you have a fully-supported Java EE app server, You can retrieve it through annotations.
Do I have to "inject" the correct Identity instance ?
You do not have to worry about it. Seam EJB interceptor Takes care of it. Go ahead.
UPDATE
but in the EJB, two different instances of Identity are injected. I'm guessing the Session context that Seam is using is not correctly linked to the Session context of the servlet ? Any ideas ?
Well, Identity component itself does not implement equals method which, by default, uses default equals implementation by using equals comparison (==). I do not know whether, for each EJB call, you have always a fresh Identity component (Maybe it explains why you have "Two different instances")
If your Servlet's share The same context, you can enable IdentityFilter as a way to wrap your Identity assigned role by using isUserInRole method. Here goes its funcionality:
A filter that provides integration between Servlet Security and the Seam identity component. This integration is accomplished by wrapping the HttpServletRequest with an HttpServletRequestWrapper implementation that delegates security-related calls to the Seam identity component.
If use use #Identity component, it is enabled by default
So instead of inject your EJB (And its #In-jected #Identity) and use
identity.hasRole("admin");
You can use
request.hasUserInRole("admin");
And maybe you want to see Setting and reading the Conversation ID And Seam and GWT
More
The ContextFilter (not enabled by default) opens access to the Seam container and its context variables to non-JSF servlets, such as Struts, Spring MVC, and Direct Web Remoting (DWR). I do not know how to use this kind of funcionality.
Your question is incredibly hard to follow and I'm not sure I understood everything. Anyway, I'll assume you are using Stateless Session Beans (since you said I could use stateful beans) which, by definition, are stateless. So how can Mary get authenticated as Joe after a call to a stateless session bean? This can't be, it doesn't make any sense.
PS: You should maybe rephrase your question and try to clearly distinguish concepts such as the HTTP Session, Session Beans (stateless, stateful?), SessionContext.

Resources