最近再弄一个关于网上商城的设计,使用的SSH(Spring SpringMVC 和 Mybatis)。出了一个问题,算是自己弄了差不多一天,想记下来以便提醒自己。

    在说问题之前先说说自己有关设计的东西。对于一个网上商城是有很多的商品分类的,就好像淘宝京东左边的那个菜单栏一样的分类,对于这个分类的处理可以使用静态的标签元素,但为了设计日后的扩展性我还是想做成动态的(就是在启动服务器的时候从数据库中读取商品分类表中的分类,将这些分类的信息封装在ApplicationContext中,再用JSTL在jsp页面进行显示,建议在建立一个Session的时候做这项工作,但因为我只是针对这一个项目,就没有考虑这么多了)。不知道这个能不能说明白,先贴几张图吧。

表titemtype

wKiom1OBTDehmB6xAAIej-FBn6U409.jpg

表的设计是不怎么规范,由于考虑了其他方面的原因,如果要按照数据设计的三范式来说,好吧,这个是个败笔。

wKioL1OBUO7DJ77mAAEIbZYy1b8861.jpg

web.xml的信息

        
dispatcherServlet
         
        
            org.springframework.web.servlet.DispatcherServlet           
        
            
contextConfigLocation
             
              
/WEB-INF/db-config.xml,/WEB-INF/web-config.xml
        
         
        
1
        
    
        
dispatcherServlet
   
        
*.do
       

db-config.xml的信息

        
    
    
    
        
        
        
        
        
    
    
    
        
        
            
    
    
    
        
        
         

web-config.xml的信息

    
            
                                 
    
                        
        
            
            
                     
        
            
            
            
            
    
        
        
    
        
                
                
                
        
    
    

上面完成了一个基础的配置,但是当自己写一个监听器实现ServletContextListener,实现类InitListener的信息如下

/** *  */package cn.edu.hnuc.listener;import java.util.List;import javax.servlet.ServletContext;import javax.servlet.ServletContextEvent;import javax.servlet.ServletContextListener;import org.apache.log4j.Logger;import cn.edu.hnuc.dao.ItemtypeMapper;import cn.edu.hnuc.entity.MyList;import cn.edu.hnuc.services.goodsView.MenuGenerator;/** 功能介绍: *  * @author yyb * 时间2014-5-24下午03:50:52 */public class InitListener implements ServletContextListener{        Logger log = Logger.getLogger(this.getClass());//与日志有关    @Resource    private MenuGenerator menuGenerator;//一个关于菜单生成类,主要功能就是从数据库中取出商品的分类信息    //menuGenerator的getter和setter方法略    public void contextDestroyed(ServletContextEvent servletcontextevent) {            }    public void contextInitialized(ServletContextEvent servletcontextevent) {        System.out.println("监听器开始起作用了");          //得到商品信息的集合MyList是将分类信息中的重要成分封装成了一个类,可不必深入        List
 mainMenu = menuGenerator.getGoodsType(MenuGenerator.TYPE.FIRSTTYPE, null);        ServletContext context = servletcontextevent.getServletContext();                if(context.getAttribute("mainMenu")==null){            context.setAttribute("mainMenu", mainMenu);            for (MyList m : mainMenu) {                log.debug("在监听器中增加的菜单项"+m.getFirstType());            }        }    }    }

做了这一步,下面要做的就是到web.xml中添加监听器的信息。wKioL1OBsO3A8q-HAAD7M1DKySo662.jpg想想应该也就可以了,下面启动服务器

wKiom1OBs8aS8cf6AAQ8h7xezfQ684.jpg

这个有些无从下手了,问度年,问谷哥终于有了那么些线索

wKiom1OBtK6jdNH6AAIC6VbDgOM719.jpg

自己又开始捣鼓开始改代码。

在原来InitListener代码中的contextInitialized方法中增加这样几行,同时去掉注解@Resourse

wKiom1OBvL6jJlKaAACpguDHSLw773.jpg

再次启服,上次的问题是没有了,不过又有新问题了

wKiom1OBteCgMveRAAFrlIO9Dsc525.jpg

wKioL1OBtbSyOM4eAAEEgMUiUtA132.jpg

wKiom1OBteDwVyxMAADTxuCPmxY301.jpg

主要是因为WEB-INF/xml-config.xml没有找到,但在我最开始的文件布局中,这个文件是确实存在的。仔细分析一下WEB-INF/xml-config.xml是在db-config.xml中引用过,在使用ClassPathXmlApplicationContext的时候,它是在classpath路径下开始引用的,加载配置文件的时候是这样的new ClassPathXmlApplicationContext("../web-config.xml","../db-config.xml")。所以在db-config下也仍然是在classpath开始进行查找的,所以在db-config.xml 中改成如下

wKiom1OBt-2QLhg5AAENXosechU716.jpg

再次启动服务器

wKioL1OBuNjS6tNWAAOyR7zqVLA386.jpg

这回监听器没有报错了,倒是DispatcherServlet开始出问题了,而且又是说配置文件没有找到,这是几个意思啊,对此,我的看法是web.xml中加载的路径是用项目的根路径开始的,所以呢复制粘贴db-config.xml,命名为db-config2.xml,主要的不同如下

wKioL1OBu6Wz6vDyAADzV9Wi8dE344.jpg

在web.xml文件中也做相应的更改

wKiom1OBvCGDKpVwAACzsM4oo4o407.jpg

ok,问题算是告一段落了

总结:其实所有的这些问题好像很乱,其实究其原因还是对Spring了解的不深刻

下面对Spring中需要注意的几点进行提炼

  1. 注解的方式执行的位置,spring的注入是在filter和listener之后的,(顺序是这样的listener >>  filter >> servlet >>  spring )

  2. 如果如果在监听器中有需要对容器中bean进行引用,就不能采用注解的方式了。只能手动的进行配置文件的读取

  3. 注意使用ClassPathXmlApplicationContext使用classpath问文件的根路径,而在配置文件中使用路径一个为"/"表示在根路径下。需要回到上一级的目录采用"../",关于Spring读取配置文件的方式,