下面到了正式开发阶段,自己创建项目并将SpringMVC、Sping以及Mybatis还有Druid和Mysql驱动包以来jar加入到pom.xml文件中。 然后就开始工作啦。
第一步:web.xml文件配置
web项目的开始就是加载web.xml文件,因此需要配置许多要启动的东西。
配置1:springMVC控制器
<servlet>
<servlet-name>securitysystem</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring-*.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>securitysystem</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
这个配置大多数人都知道,不过拦截路径/是默认不被springMVC管理的,许多人配置/*后面会对其解释这样设置的原因。springMVC用户的所有请求进行拦截,并且将所有spring配置文件进行初始化。下面是我的spring文件:
对所有请求拦截有一个问题,那就是我们jsp或者html中引用的js、css等文件都会被当成请求拦截,因此就导致静态文件加载不出来。这里解决方案有:
1.修改拦截地址 / 变为 *.action.这样做的缺点是每个请求后面都要添加.action,很麻烦
2.将所有静态资源放入指定文件夹,我的是在webapp文件夹下新建一个resource文件夹,将其放入其中,然后在springMVC配置文件中将其代表静态资源的文件夹抛出拦截。
然后在spring-web.xml文件中添加:
设置静态资源路径
<mvc:resources location="/resources/" mapping="/resources/**" cache-period="3600"/>
实现路径的转发和资源的请求
<mvc:view-controller path="/" view-name="login"/>
<mvc:view-controller path="/home" view-name="home"/>
<mvc:view-controller path="/index" view-name="index"/>
<mvc:view-controller path="/top" view-name="top"/>
<mvc:view-controller path="/left" view-name="left"/>
<mvc:view-controller path="/updatePwd" view-name="updatePwd"/>
<mvc:view-controller path="/typeList" view-name="TypeList"/>
<mvc:view-controller path="/sMPlatform" view-name="SMPlatform"/>
<mvc:view-controller path="/illegalDevice" view-name="IllegalDevice"/>
拦截器,将静态资源请求抛出在外
<mvc:interceptors>
<!-- 多个拦截器,顺序执行 -->
<mvc:interceptor>
<mvc:mapping path="/**"/><!-- 拦截哪些请求的设置 -->
<mvc:exclude-mapping path="/resources/**"/><!-- 使用拦截器时,需加上这句话,否则静态资源被拦截 -->
<bean class="com.youotech.usbmonitor.interceptor.LoginInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
<mvc:view-controller/>此标签用以在springMVC配置文件中实现路径的转发和资源的请求。其中path表示为请求的路径,view-name表示为你需要做的资源操作,其中path会首先匹配requestmapping路径,匹配不到后再进行view-name的资源寻找。view-name中可以输入相对于视图解析器的路径,也可以输入类似于redirect:路径,然后匹配次requestmapping
好了完整的spring-web贴出如下:
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!-- 注解 -->
<mvc:annotation-driven/>
<!-- 扫描包 -->
<context:component-scan base-package="com.youotech.usbmonitor.controller"/>
<!-- 允许访问路径 -->
<mvc:resources location="/resources/" mapping="/resources/**" cache-period="3600"/>
<!-- 视图解析配置 -->
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
</list>
</property>
<property name="defaultViews">
<list>
<bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>
</list>
</property>
</bean>
<mvc:view-controller path="/" view-name="login"/>
<mvc:view-controller path="/home" view-name="home"/>
<mvc:view-controller path="/index" view-name="index"/>
<mvc:view-controller path="/top" view-name="top"/>
<mvc:view-controller path="/left" view-name="left"/>
<mvc:view-controller path="/updatePwd" view-name="updatePwd"/>
<mvc:view-controller path="/typeList" view-name="TypeList"/>
<mvc:view-controller path="/sMPlatform" view-name="SMPlatform"/>
<mvc:view-controller path="/illegalDevice" view-name="IllegalDevice"/>
<!-- springMVC统一异常处理 -->
<bean id="exceptionResolver" class="com.youotech.usbmonitor.exception.ExceptionHandler"/>
<!-- 拦截器 -->
<mvc:interceptors>
<!-- 多个拦截器,顺序执行 -->
<mvc:interceptor>
<mvc:mapping path="/**"/><!-- 拦截哪些请求的设置 -->
<mvc:exclude-mapping path="/resources/**"/><!-- 使用拦截器时,需加上这句话,否则静态资源被拦截 -->
<bean class="com.youotech.usbmonitor.interceptor.LoginInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
</beans>
好了客户请求转发以及视图渲染完成,下面来看看spring容器加载以及和Mybatis整合的配置
配置2:spring容器配置
spring的配置首先就是扫描包,将所有bean初始化加载到IOC容器,刚才的web里面已经扫描了控制层的包,即所有@Controller注解的类已经被加载到IOC容器,现在把业务层即@Service的加载到IOC容器:
<context:component-scan base-package="com.youotech.usbmonitor.service"/>
这里说个问题:我以前是将Spring的所有bean注解一起扫描,即配置的base-backage为com.youotech.*。就是说所有包下所有bean都被加载IOC容器,出现的问题就是在控制层中@AutoWired的Service层注入的对象为空。原因就是Sping作为父容器和SpringMVC这个子容器不互通,导致的。具体详情在我的其他文章里面讲解。解决方法就是要么像我这样分包扫描,要么就是全部扫描,然后再父容器中将@Controller注解刨除:
<context:component-scan base-package="com.youo">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
是不是就剩下Dao层的注解没扫描了,不急。现在就开始搞Dao层。
我们知道Dao就是和Mybatis有关了,那么先连接数据库,连接信息写道配置文件.properties中,然后将其加入到全局Map中,配置如下:
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
</list>
</property>
</bean>
上面的作用就是下面再配置文件中获取.properties中文件内容可以直接使用${属性名}拿到配置信息值。
然后配置数据库连接池信息:
<!--MySQL数据源配置-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="url" value="${jdbc.url}"/>
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="${druid.initialSize}"/>
<property name="minIdle" value="${druid.minIdle}"/>
<property name="maxActive" value="${druid.maxActive}"/>
<!-- 配置获取连接等待超时时间 -->
<property name="maxWait" value="${druid.maxWait}"/>
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="${druid.timeBetweenEvictionRunsMillis}"/>
<!-- 配置一个连接池中最小生存的时间,单位毫秒 -->
<property name="minEvictableIdleTimeMillis" value="${druid.minEvictableIdleTimeMillis}"/>
<property name="validationQuery" value="${druid.validationQuery}"/>
<property name="testWhileIdle" value="${druid.testWhileIdle}"/>
<!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
<property name="poolPreparedStatements" value="${druid.poolPreparedStatements}"/>
<property name="maxPoolPreparedStatementPerConnectionSize"
value="${druid.maxPoolPreparedStatementPerConnectionSize}"/>
<!-- 配置监控系统拦截的filters,去掉后监控界面sql无法统计 -->
<property name="filters" value="${druid.filters}"/>
</bean>
jdbc.properties文件
jdbc.url = jdbc:mysql://IP/数据库名?useUnicode=true&characterEncoding=UTF-8
jdbc.driverClassName = com.mysql.jdbc.Driver
jdbc.username = 账号
jdbc.password = 密码
#alibaba druid ext props
druid.testOnBorrow = false
druid.validationQuery = SELECT 1 FROM DUAL
druid.validationQuery1 = SELECT 1 FROM Device
druid.testWhileIdle = true
druid.testOnReturn = false
druid.initialSize = 15
druid.minIdle = 10
druid.maxActive = 50
druid.maxWait = 60000
druid.timeBetweenEvictionRunsMillis = 60000
druid.minEvictableIdleTimeMillis = 300000
druid.poolPreparedStatements = true
druid.maxPoolPreparedStatementPerConnectionSize = 20
#stat,log4j
druid.filters = stat
druid.removeAbandoned = true
druid.removeAbandonedTimeout = 1800
druid.logAbandoned = true
下面配置SqlSessionFactory
<!--配置sqlSessionFactory 并将数据源注入-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--注入数据源-->
<property name="dataSource" ref="dataSource"/>
<!--指定要使用到到mybatis配置文件-->
<!--用于配置mapper映射xml-->
<property name="mapperLocations" value="classpath:mdl-mapper-mybatis/*Mapper.xml"/>
</bean>
下面将其映射到指定包下,并加入到IOC容器(也就是前面没扫描的Dao)
<!-- 创建数据映射器-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.youotech.usbmonitor.dao"/>
</bean>
这里都是接口,Mybatis会自动按配置文件中对应接口注入。
最后是事务管理:
采用注解式事务
<!-- 配置基于注解的声明式事务,默认使用注解来管理事务行为 -->
<tx:annotation-driven proxy-target-class="false" transaction-manager="transactionManager"/>
同时对数据源进行事务管理
<!-- 对数据源进行事务管理 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
好了完整的sping-dao.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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
</list>
</property>
</bean>
<!--MySQL数据源配置-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="url" value="${jdbc.url}"/>
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="${druid.initialSize}"/>
<property name="minIdle" value="${druid.minIdle}"/>
<property name="maxActive" value="${druid.maxActive}"/>
<!-- 配置获取连接等待超时时间 -->
<property name="maxWait" value="${druid.maxWait}"/>
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="${druid.timeBetweenEvictionRunsMillis}"/>
<!-- 配置一个连接池中最小生存的时间,单位毫秒 -->
<property name="minEvictableIdleTimeMillis" value="${druid.minEvictableIdleTimeMillis}"/>
<property name="validationQuery" value="${druid.validationQuery}"/>
<property name="testWhileIdle" value="${druid.testWhileIdle}"/>
<!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
<property name="poolPreparedStatements" value="${druid.poolPreparedStatements}"/>
<property name="maxPoolPreparedStatementPerConnectionSize"
value="${druid.maxPoolPreparedStatementPerConnectionSize}"/>
<!-- 配置监控系统拦截的filters,去掉后监控界面sql无法统计 -->
<property name="filters" value="${druid.filters}"/>
</bean>
<!--配置sqlSessionFactory 并将数据源注入-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--注入数据源-->
<property name="dataSource" ref="dataSource"/>
<!--指定要使用到到mybatis配置文件-->
<!--<property name="configLocation" value="classpath:config/config.xml"/>-->
<!--用于配置mapper映射xml-->
<property name="mapperLocations" value="classpath:mdl-mapper-mybatis/*Mapper.xml"/>
</bean>
<!-- 创建数据映射器-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.youotech.usbmonitor.dao"/>
</bean>
<!-- 对数据源进行事务管理 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<context:component-scan base-package="com.youotech.usbmonitor.service"/>
<tx:annotation-driven proxy-target-class="false" transaction-manager="transactionManager"/>
</beans>
至于spring-service.xml就不管了,里面基本没啥。
总结:
1.再配置spingMVC时拦截请求的格式设置需要处理静态资源请求不被拦截
2.注意Spring容器以及SpringMVC子容器扫描引发的注释为null问题