最近再弄一个关于网上商城的设计,使用的SSH(Spring SpringMVC 和 Mybatis)。出了一个问题,算是自己弄了差不多一天,想记下来以便提醒自己。
在说问题之前先说说自己有关设计的东西。对于一个网上商城是有很多的商品分类的,就好像淘宝京东左边的那个菜单栏一样的分类,对于这个分类的处理可以使用静态的标签元素,但为了设计日后的扩展性我还是想做成动态的(就是在启动服务器的时候从数据库中读取商品分类表中的分类,将这些分类的信息封装在ApplicationContext中,再用JSTL在jsp页面进行显示,建议在建立一个Session的时候做这项工作,但因为我只是针对这一个项目,就没有考虑这么多了)。不知道这个能不能说明白,先贴几张图吧。
表titemtype
表的设计是不怎么规范,由于考虑了其他方面的原因,如果要按照数据设计的三范式来说,好吧,这个是个败笔。
web.xml的信息
<servlet> <servlet-name>dispatcherServlet</servlet-name> <!-- 将服务器的控制权交给Spring --> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <!-- 需要加载的配置文件 --> <param-value>/WEB-INF/db-config.xml,/WEB-INF/web-config.xml</param-value> </init-param> <!-- 1表示服务器启动的时候就加载该类 --> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <!-- 设置对那些请求进行控制,这里表示对所以以.do结尾的请求进行控制 --> <url-pattern>*.do</url-pattern> </servlet-mapping>
db-config.xml的信息
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <!-- 引入jdbc配置文件 --> <!--<context:property-placeholder location="classpath:jdbc.properties" />--> <!--创建jdbc数据源 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" > <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/graduation_project?useUnicode=true&characterEncoding=utf8" /> <property name="username" value="root" /> <property name="password" value="123456" /> </bean> <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx --> <!--<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean>--> <!-- 创建SqlSessionFactory,同时指定数据源 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="configLocation" value="../xml-config.xml"></property> <property name="dataSource" ref="dataSource" /> </bean> <!-- 可通过注解控制事务 --> <!--<tx:annotation-driven />--> <!-- Mapper接口所在包名,Spring会自动查找其下的Mapper --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="cn.edu.hnuc.dao" /> <property name="sqlSessionFactory" ref="sqlSessionFactory"></property> </bean> </beans>
web-config.xml的信息
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd " > <context:component-scan base-package="cn.edu.hnuc" > </context:component-scan> <!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射 --> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/> <!-- Controller方法调用规则定义 --> <bean id="paraMethodResolver" class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver"> <property name="paramName" value="action"/> <property name="defaultMethodName" value="list"/> </bean> <!-- 页面View层基本信息设定 --> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <!--<property name="prefix" value="/myjsp/"/>--> <property name="suffix" value=".jsp"/> </bean> <!-- 有了注解后 这些就可以省略了 --> <!-- servlet映射列表,所有控制层Controller的servlet在这里定义,当加入MVC的注解功能后,不用 --> <!--<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="city.do">cityController</prop> </props> </property> </bean>--> <!--<bean id="cityController" class="com.hnipo.controller.CityController"> <property name="cityServices" ref="cityServices"></property> </bean>--> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/*" /> <!--<mvc:mapping path="/test/*" />--> <bean class="interceptor.InitInterceptor"></bean> </mvc:interceptor> </mvc:interceptors> </beans>
上面完成了一个基础的配置,但是当自己写一个监听器实现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<MyList> 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中添加监听器的信息。想想应该也就可以了,下面启动服务器
这个有些无从下手了,问度年,问谷哥终于有了那么些线索SSH框架问题——listener(监听器)的配置报错:javax.naming.NameNotFoundException: Name com………… 下面对其关键信息进行截图
自己又开始捣鼓开始改代码。
在原来InitListener代码中的contextInitialized方法中增加这样几行,同时去掉注解@Resourse
再次启服,上次的问题是没有了,不过又有新问题了
主要是因为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 中改成如下
再次启动服务器
这回监听器没有报错了,倒是DispatcherServlet开始出问题了,而且又是说配置文件没有找到,这是几个意思啊,对此,我的看法是web.xml中加载的路径是用项目的根路径开始的,所以呢复制粘贴db-config.xml,命名为db-config2.xml,主要的不同如下
在web.xml文件中也做相应的更改
ok,问题算是告一段落了
总结:其实所有的这些问题好像很乱,其实究其原因还是对Spring了解的不深刻
下面对Spring中需要注意的几点进行提炼
注解的方式执行的位置,spring的注入是在filter和listener之后的,(顺序是这样的listener >> filter >> servlet >> spring )
如果如果在监听器中有需要对容器中bean进行引用,就不能采用注解的方式了。只能手动的进行配置文件的读取
注意使用ClassPathXmlApplicationContext使用classpath问文件的根路径,而在配置文件中使用路径一个为"/"表示在根路径下。需要回到上一级的目录采用"../",关于Spring读取配置文件的方式,Spring中加载xml配置文件的六种方式
转载于:https://blog.51cto.com/yangyingbin/1416898