【问题标题】:Store List of Objects in Session Scope Spring MVC's ApplicationListener在 Session 范围内存储对象列表 Spring MVC 的 ApplicationListener
【发布时间】:2012-11-16 17:21:36
【问题描述】:

我试图在我的 Spring MVC 应用程序的会话中存储一个对象列表,以便我可以在我的 JSP 中遍历它们以在下拉列表中创建选项。

阅读帖子和博客大约两个小时后,我感到非常困惑。事实上,我什至不知道从哪里开始。任何人都可以指出符合以下标准的基于 Spring 的解决方案 [文档、教程、示例] 的方向吗?

  1. 列表的值是从数据库表中提取的。
  2. 该列表在应用程序启动期间加载。
  3. 它不直接访问控制器内的会话。

【问题讨论】:

    标签: java spring spring-mvc


    【解决方案1】:

    你应该定义一个spring bean。您可以在this question 的回答中了解如何在启动时在 bean 中运行代码。像 ApplicationListener 这样的东西应该可以工作。在该启动代码中,您可以将表加载到内存中(听起来这就是您要查找的内容。)

    在您的控制器中注入 spring bean,它具有获取所需值的方法。然后,您将这些值添加到您的请求处理程序中的模型(而不是会话),模型由视图(您的 JSP 页面)使用,该视图可以迭代这些值并显示它们。

    【讨论】:

    • 感谢您的帮助,您对这种方法有何看法:2mohitarora.blogspot.com/2012/06/… 这对我来说似乎有点粗略。
    • 感谢 Joel,我能够按照您的指示进行所有设置,但是我使用 HandlerInterceptor 将我的列表放入请求中。
    【解决方案2】:

    通过实现org.springframework.beans.factory.InitializingBean 接口创建一个读取值并放入列表的类,例如:

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

    在配置文件中添加bean:

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

    访问它:

       ListLoader myListLoader= (ListLoader)context.getBean("myListLoader");
       List<String> myValues= = myListLoader.getMyList();
    

    【讨论】:

    • InitializingBean 有注解吗?
    • @kmb385:我不这么认为。如果您想要注释,那么您可能想尝试使用 @PostContruct,即来自 J2EE 的 javax.annotation.PostConstruct
    • 我不确定,我查看了解决方案并决定使用 ApplicationListener,因为 joel 链接的问题中的一个答案表明它在所有 bean 都被实例化后才进行设置。因为我需要我的存储库,所以我认为这是最好的方法。
    • @kmb385:确保你使用正确的监听器,否则它在后台的过度杀伤力,因为监听器的寿命比需要的长(在你的情况下)。
    • @kmb385:我不是在质疑最终结果。我要说的是,从概念上讲,侦听器的寿命更长,并等待事件发生。在您的情况下,您只想在我猜到(在上下文加载时)初始化您的列表。
    【解决方案3】:

    为了更清楚地说明我是如何解决这个问题的,我选择回答我自己的问题。

    1.正如 DigitalJoel 的回答中所建议的,我创建了一个 ApplicationListener bean。每次刷新上下文时都会触发此侦听器。

    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。接下来,我在我的应用程序配置中注册了这个 bean。

    application-context.xml (Spring-Config)

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

    3。然后为了将这个 bean 放入每个请求中,我创建了一个 HandlerInterceptorAdapter,它在每次收到请求时执行。在这个 bean 中,我自动装配了 LookupLoader 并在请求中设置了我的列表。

    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.在 Spring MVC Web 应用配置中注册 HandlerInterceptor

    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.通过 JSP & JSTL 访问列表

    <c:forEach var="category" items="${skillCategories}">
        ${category.name}
    </c:forEach>
    

    【讨论】:

    • 所以你没有使用 spring reqeust 处理程序,你可以将它添加到模型中,也许作为一个模型属性?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-04
    • 1970-01-01
    • 2019-10-15
    • 2022-07-06
    • 2017-07-08
    • 1970-01-01
    • 2014-10-17
    相关资源
    最近更新 更多