Announcement Announcement Module
Collapse
No announcement yet.
Accessing spring managed session beans from jsp (without Spring MVC!) Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Accessing spring managed session beans from jsp (without Spring MVC!)

    Does anyone know how to access spring managed session beans from jsp?

    I have in my web.xml :-

    Code:
    	<context-param>
    	  <param-name>contextConfigLocation</param-name>
    	  <param-value>/WEB-INF/webapp-beans.xml</param-value>
    	</context-param>
    	
    	<listener>
    	  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    	</listener>
    and in my webapp-beans.xml :-

    Code:
    <bean id="SessionInfo" class="myapp.Session" scope="session">
    		<property name="application" ref="application" />
    </bean>
    I would like to be able to put this in my jsp:-
    Code:
    <jsp:useBean id="SessionInfo" class="myapp.Session" scope="session" />
    ...and have access to the Spring managed bean "SessionInfo".

    What happens is the constructor of the Session class is called from the jsp page, which is to be expected if the Session class is not in the httpSession. But the Session class is a Spring managed bean with scope="session", so bearing in mind I'm not using the Spring MVC framework (and I'm not ready to make that commitment yet!), Is there some automatic way to inject some Spring managed beans into the jsp page for the appropriate scope?

    Thanks in advance..
    Phil.

  • #2
    Hmm injecting beans into a jsp isn't going to happen .

    However you can access the ApplicationContext and retrieve beans from there.

    Code:
    <%
    ApplicationContext context = RequestContextUtils.getWebApplicationContext(request);
    SessionInfo info = context.getBean("SessionInfo");
    %>

    Comment


    • #3
      When you use a spring-managed session bean, spring prefixes it with a string "scopedTarget." (including the dot) and puts in session.

      So using the jsp bean, you cannot retrieve it. You cannot have a "." in the jsp bean's id. Also the "." hinders the usage of jstl, for eg, you cannot do a:

      <c:out value=${scopedTarget.sessionInfo.value}"/>

      JSTL will try to translate to getScopedTarget().getSessionInfo().getValue() which is obviously not there.

      I wish the prefix was configurable.

      But, instead of having to rely on spring's ApplicationContext, you can do this:

      <% pageContext.getSession("scopedTarget.SessionInfo") ; %>

      This would retrieve you the actual spring-managed session object.

      Comment


      • #4
        Thanks for taking the time to reply and for your solution.

        I searched for a reference to scopedTarget and found it in org.springframework.aop.config.ScopedProxyBeanDefi nitionDecorator which only seems to come into play if you have <aop:scope/> in the bean definition. I'm trying to do this with the bare minimum and I don't want the aop stuff just yet.

        I do have a solution which though it may not be perfect, is simple enough and does the job.

        I added a HttpSessionListener to the servlet configuration xml

        Code:
        	
        <listener>
           <listener-class>
              myapp.spring.SpringSessionListener
           </listener-class>
        </listener>
        The implementation is
        Code:
        public class SpringSessionListener implements HttpSessionListener
        {
        	private boolean eventOccurring_ = false;
        
        	public synchronized void sessionCreated(HttpSessionEvent arg0)
        	{
        		if (!eventOccurring_)
        		{
        			eventOccurring_ = true;
        			HttpSession session = arg0.getSession();
        			WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(session.getServletContext());
        			String[] allBeans = ctx.getBeanNamesForType(ISessionBean.class);
        			
        			for (String bean : allBeans)
        			{
        				Object obj = ctx.getBean(bean);
        				session.setAttribute(bean, obj);
        			}
        			
        			eventOccurring_ = false;
        		}
        	}
        
        	public void sessionDestroyed(HttpSessionEvent arg0)
        	{
        	}
        }
        which simply puts all the session beans identified by a marker interface ISessionBean and puts them in the httpSession whenever a new session is created.

        The eventOccurring_ variable is to stop the recursive loop when ctx.getBean(bean) calls a getSession, which notifies this listener!

        I'd have preferred a way of identifying the session beans with something like ctx.getBeansForScope(RequestAttributes.SCOPE_SESSI ON) doing away with the marker interface, but alas, I could not find such method.

        anyway thanks again.
        Phil Wilkinson.

        Comment

        Working...
        X