0

I am trying to store a list of objects in my Spring MVC application's session so that I may iterate through them within my JSPs to create options in a drop down.

After about two hours of reading through posts and blogs I am very confused. In fact, I don't even know where to start. Can anyone point me in the direction of a Spring based solution [documentation, tutorials, examples] that meets the following criteria?

  1. Values for the list are pulled from a database table.
  2. The list is loaded during application startup.
  3. It does not directly access the session within a controller.
Kevin Bowersox
  • 93,289
  • 19
  • 159
  • 189

3 Answers3

1

You should define a spring bean. You can see how to run code within the bean at startup in the answer to this question. Something like an ApplicationListener should work. In that startup code you can load the table into memory (it sounds like that is what you are looking for.)

Within your controller you inject the spring bean which has a method to get the values you need. You then add those values to the Model (not the session) in your request handler and the Model is used by the view (your JSP page) which can iterate over the values and display them.

Community
  • 1
  • 1
digitaljoel
  • 26,265
  • 15
  • 89
  • 115
  • Thanks for the help, what is your opinion of this method: http://2mohitarora.blogspot.com/2012/06/load-reference-data-from-database-in.html It seems kind of sketchy to me. – Kevin Bowersox Nov 16 '12 at 17:42
  • Thanks Joel, I was able to get everything setup following your directions, however I used a HandlerInterceptor to put my list in the request. – Kevin Bowersox Nov 16 '12 at 19:14
1

Create a class which reads the values and puts in list by implementing org.springframework.beans.factory.InitializingBean interface e.g.:

      public class ListLoader implements InitializingBean{
       ....
       ....
       public List<String> getMyList(){
         ...
         ...
       }
     }

Add the bean in configuration file:

   <bean id="myListLoader" class="com.....ListLoader">
    ...
   </bean>

To access it:

   ListLoader myListLoader= (ListLoader)context.getBean("myListLoader");
   List<String> myValues= = myListLoader.getMyList();
Yogendra Singh
  • 33,927
  • 6
  • 63
  • 73
  • Is there an annotation for InitializingBean? – Kevin Bowersox Nov 16 '12 at 17:46
  • @kmb385: I don't think so. If you want annotation, then you may want to try using `@PostContruct` i.e. `javax.annotation.PostConstruct` from J2EE. – Yogendra Singh Nov 16 '12 at 17:56
  • I'm not sure, I took a look at the solutions and decided to go with the ApplicationListener because one of the answers in the question joel linked suggested that it gets setup after all beans are instantiated. Since I needed my repository, I thought that was the best way. – Kevin Bowersox Nov 16 '12 at 19:18
  • 1
    @kmb385: Make sure your use right listener otherwise its overkill in the background as listeners are something alive longer than required(in your case). – Yogendra Singh Nov 16 '12 at 19:21
  • I used the ContextRefreshEvent, will that work? I have documented my solution below in an answer. I would value your thoughts or suggestions. – Kevin Bowersox Nov 16 '12 at 19:22
  • 1
    @kmb385: I am not questioning about end result. All I am saying is that listners by concept are alive longer and wait for the events. In your case, you wanted to initialize your list only once I guess(on context load). – Yogendra Singh Nov 16 '12 at 19:25
  • Thats exactly what I wanted to do. I null check my list in the listener to make sure I don't reach back to the database to populate it. – Kevin Bowersox Nov 16 '12 at 19:29
1

Just to provide some further clarity into how I resolved this problem, I have chosen to answer my own question.

1. As suggested in DigitalJoel's answer, I created an ApplicationListener bean. This Listener is fired each time the context is refreshed.

LookupLoader.java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.tothought.entities.SkillCategory;
import org.tothought.repositories.SkillCategoryRepository;

public class LookupLoader implements ApplicationListener<ContextRefreshedEvent> {

    @Autowired
    SkillCategoryRepository repository;

    private List<SkillCategory> categories;


    public List<SkillCategory> getCategories() {
        return categories;
    }

    public void setCategories(List<SkillCategory> categories) {
            this.categories = categories;           
    }

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        if(this.categories == null){
            this.setCategories(repository.findAll());               
        }
    }
}

2. Next, I registered this bean in my application configuration.

application-context.xml (Spring-Config)

<bean id="lookupLoader"
    class="org.tothought.controllers.initializers.LookupLoader" />

3. Then to place this bean in each request I created a HandlerInterceptorAdapter that is executed each time a request is received. In this bean I autowired the LookupLoader and set my list in the request.

LookupHandlerInterceptor.java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.tothought.controllers.initializers.LookupLoader;

public class LookupHandlerInterceptor extends HandlerInterceptorAdapter {
    @Autowired
    LookupLoader loader;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        request.setAttribute("skillCategories", loader.getCategories());
        return super.preHandle(request, response, handler);
    }
}

4. Register the HandlerInterceptor within the Spring MVC web application configuration

servlet-context.xml

<!-- Intercept request to blog to add paging params -->
<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="org.tothought.controllers.interceptors.LookupHandlerInterceptor" />
    </mvc:interceptor>
</mvc:interceptors>

5. Access the list via JSP & JSTL

<c:forEach var="category" items="${skillCategories}">
    ${category.name}
</c:forEach>
Kevin Bowersox
  • 93,289
  • 19
  • 159
  • 189
  • so are you not using spring reqeust handlers where you could just add it to the model, perhaps as a modelattribute? – digitaljoel Nov 16 '12 at 22:39