Spring MVC 3.0 accessing Session Variable - java

I have the following problem, I have configured the following class which should be stored in session.
<bean id="Users" class="com.doolloop.DlUser" scope="session">
<aop:scoped-proxy/>
</bean>
Then I in my Dispatcher servlet I would like to access this class user and set
#RequestMapping(value="/authenticate.do",method = RequestMethod.POST)
public String sampleAuthentication(#Valid Person person, BindingResult result,
Map model,HttpServletRequest request){
...... /some code
HttpSession session = request.getSession();
DlUser user = (DlUser) session.getAttribute("Users");
/// some uses for user object
}
The problem is that I'm always getting null Value of user object.
What am I doing wrong?
Second problem, I read in articles that accessing HttpSession is not thread-safe, how can it be done safe way? Should be kind of Singleton? Why this is not Thread Safe operation?
Thank you in advance.
Danny.

That's a special case when you want to inject a bean with a shorter scope into a bean with a longer scope (i.e. a session-scoped bean into a singleton-scoped bean)
You can use a lookup-method:
<bean id="yourSingletonBean"
class="your.singleton.BeanClass">
<lookup-method name="getDLUser" bean="Users"/>
</bean>
You'll need to make your singleton bean abstract, and create an abstract method public DLUser getDLUser()
That, however, is not a perfect solution. The idea is to hold in the session as little as possible. If you don't need to store a bean in the session, but only the current user, you can easily call session.setAttribute(..) when the user logs in, and then access the current user with session.getAttribute(..), without the user being a bean at all.
A way that I chose for the current user in my application is to create a custom #SessionAttribute annotation. See this question on how to achieve that.

objects scoped "session" are not STORED in session, they are available to the session through the regular direct injection paradigm. It's just that they are session-tied. So, if you need to have this available, you need to inject this bean into your controller. Read here for more info.

Related

How long does an spring initialized bean live?

When i run the first petittion of a bean's method (let's say method A) on the server everything seems ok, but when running for the second time any petition on this carrierRESTWS bean (let's say method B), the dao being used is the same carrierDAO instance. How can i avoid having this problem and making the injection use a new instance of the dao each time this carrierRESTWS bean is being called?
Beans configuration inside xml file:
<bean id="carrierRESTWS" class="ar.com.anovo.controllers.rest.CarrierRESTWS">
<property name="carrierDAO" ref="carrierDAO"/>
</bean>
<bean id="carrierDAO" class="ar.com.anovo.dao.CarrierDAO"></bean>
Set the scope of "carrierDAO" to "prototype":
<bean id="carrierDAO" class="ar.com.anovo.dao.CarrierDAO" scope="prototype" />
This will create a new instance, once an injection is required.
More about scopes can be found in the Spring Doc.
Your beans are singleton beans, so they live for as long as the Spring Container lives, which basically means for as long as your program is running, which again means for as long as your webapp is running, which could theoretically be years.
Since your controllers and your DAO classes have of course been coded to be stateless, and support multi-threading, you shouldn't have a problem with a single shared instance.
The default scope in spring is singleton, so you need to explicitly set the scope which makes a new instance each time as #Stefan indicates with prototype.

spring mvc exception handler with #RequestBody

In my Spring MVC application I have a number of methods that use #RequestBody to bind to domain objects I've defined (specifically, from JSON using Jackson).
I'm currently using a simple view for exceptions as follows:
<bean id="exceptionHandler" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="defaultErrorView" value="errorXmlView" />
</bean>
<bean id="errorXmlView" class="com.example.MyCustomXmlView" />
My question is, inside MyCustomXmlView, which currently just extends AbstractView, is there a way I can get access to the object that was bound with #RequestBody? Assuming, that is, that it got that far and it wasn't a binding exception. For example, is there some kind of request-scoped bean I could call upon, or a way to get the object injected into the model for my exception view? If not, is there a different way of defining an exception resolver that would allow me to do that?
Have you considered the #ExceptionHandler annotation? The spring documentation has an example of its usage, and I imagine you can create a custom exception that will hold onto your model, which you should then be able to access in your exception handling method.
I often times capture controller method parameters with a ThreadLocal, and then store them for later use in logging, etc. The best way I've found is to use an #Aspect (or whatever AOP strategy you prefer) to intercept the controller methods and store the method parameters for later use.

Spring Injection & Globally initialized objects

I have a spring injected service
class A{
List l = new ArrayList();
public m1(){
//do some additions in list
}
public m2(){
//do some new additions in list
}
}
Now because creating of objects of A, is in the hands of spring the behavior of program is not what is expected. (I expect list to be available empty always but not initialized by methods for some wired reason)
Will Spring always create only one instance of A, so that list l will keep on growing, I have configured bean as singleton in application context.
If yes, naturally I must initialize the list inside the functions m1 & m2 or callee must past the reference, and in my case callee being struts2 actions they are not singleton so this issue can be solved?
Or
Does spring provide any support in configuration to initialize member variables at every call or something else?
More generally what are best practices to have in writing services injected by spring about using member variables/ local variables for performance & efficiency.
Trying to answer following :
Does spring provide any support in configuration to initialize member variables at every call or something else?
By default Spring beans are singleton. Initialized only once and use the same object again and again.
However, if requirement changes as you asked. You need to understand scope attribute provided by the Spring.
<bean id="id" class="com.test.TP" scope="prototype">
</bean>
Refer following for detail understanding.
Scope Description
singleton
Scopes a single bean definition to a single object instance per
Spring IoC container.
prototype
Scopes a single bean definition to any number of object instances.
request
Scopes a single bean definition to the lifecycle of a single HTTP
request; that is each and every HTTP request will have its own
instance of a bean created off the back of a single bean definition.
Only valid in the context of a web-aware Spring ApplicationContext.
session
Scopes a single bean definition to the lifecycle of a HTTP Session.
Only valid in the context of a web-aware Spring ApplicationContext.
global session
Scopes a single bean definition to the lifecycle of a global HTTP
Session. Typically only valid when used in a portlet context. Only
valid in the context of a web-aware Spring ApplicationContext.
http://static.springsource.org/spring/docs/3.0.0.M3/spring-framework-reference/html/ch04s04.html
It is also possible to have user defined scope such as thread scope.
You can configure your bean as follows:-
<bean id = "serviceBeanA" class = "somepkg.A" scope="prototype">
<property name = "l">
<value>
<list>
<value>ABC</value>
.....
</list>
</value>
</property>
</bean>
I'm not sure if I understand the question but your sample class should work fine with spring. Spring will call the default constructor unless you pass in constructor args in the configuration file. As long as you have an id="..." in the bean then it will create a singleton of that class. Then, the first class that calls a.m1() will see l as being an empty list.
What may be happening is that you have multiple instances of A being created. See here about Spring singletons versus non. To quote:
Beans are defined to be deployed in one of two modes: singleton or non-singleton. (The latter is also called a prototype, although the term is used loosely as it doesn't quite fit). When a bean is a singleton, only one shared instance of the bean will be managed and all requests for beans with an id or ids matching that bean definition will result in that one specific bean instance being returned.
So if you don't have an id or name specified in your Spring configuration then you might get multiple instances of A created.
The non-singleton, prototype mode of a bean deployment results in the creation of a new bean instance every time a request for that specific bean is done. This is ideal for situations where for example each user needs an independent user object or something similar.

Get session-scoped bean from GenericFacesPortlet

Is it somehow possible to accesse a sesssion-scoped bean in a class extending the GenericFacesPortlet?
Is a portlet even aware of the FacesContext?
What do I want to achieve?
I want to serve a file through the serveResource() method. The file's content should be retrieved from a bean implementing the method getResourceContent().
But unfortunately, I'm getting null when calling FacesContext.getCurrentInstance().
For your information: I'm using the JBoss Portlet Bridge in Version 2.1.0.FINAL.
The FacesContext will always be null in the GenericFacesPortlet. The GenericFacesPortlet creates the bridge and initializes it. The Bridge is actually creating the FacesContext and executing the JSF life cycle. From your GenericFacesPortlet point of view the FacesContext is not yet created (null).
In order to achieve what you want, you can grab the bean from the session. In order to do that you must use:
YourBean yourBean = (YourBean) request.getPortletSession().getAttribute("yourBeanName");
where "yourBeanName" is the name you used in the faces-config.xml when you defined YourBean.
Cheers!

How do I force a spring container not to return a singleton instance of a bean?

When I call getBean(name) on a BeanFactory, I get back an instance of the bean defined in the application context. However, when I call getBean(name) again (with the same name,) I get the same instance of the bean back. I understand how this would be desirable in some (many?) cases, but how do I tell the BeanFactory to give me a new instance?
Example Spring configuration (tersely...I've left out some verbosity, but this should get the point across):
<beans>
<bean id="beanA" class="misc.BeanClass"/>
</beans>
Example Java:
for(int i = 0;i++;i<=1) {
ApplicationContext context = ClassPathXmlApplicationContext("context.xml");
Object o = context.getBean("beanA");
System.out.println(o.toString()); // Note: misc.BeanA does not implement
// toString(), so this will display the OOID
// so that we can tell if it's the same
// instance
}
When I run this, I get something like:
misc.BeanClass#139894
misc.BeanClass#139894
Note that both have the same OOID...so these are the same instances...but I wanted different instances.
You need to tell spring that you want a prototype bean rather than a singleton bean
<bean id="beanA" class="misc.BeanClass" scope="prototype"/>
This will get you a new instance with each request.
The default scope is singleton, but you can set it to prototype, request, session, or global session.

Categories