前言
出于目的
这篇文章写出来大体没什么技术价值,主要是写给小白入手的,因为我也已经加入公司团队,在项目框架这一块完全不需要普通开发者接手,不过在自己实际从零开始搭建过程中,就出现一系列的问题,网上也有很多关于SSM整合搭建的博客,只是很多要么是copy人家旧版本的,要么不完整,遇到一个问题找一个问题,对于小白来说都不是很友好。况且不同的开发环境(eclipse、IDEA)不同的项目架构差异也大,对新手来说在环境搭建耗费太长,就不利于后期深入学习了,所以就有必要将自己徒手搭建踩过的坑徒手记录下来,就写出这篇文章吧
整体规划
这不是一篇文章,是多篇文章构成的集合,因为搭建环境有太多形式,在这一系列的文章会分多种形式讨论,分别在eclipse和IDEA中搭建单项目SSM,多项目依赖的SSM,以及需要配合dubbo&zookeeper使用的微服务SSM,小伙伴们可以根据自己的实际需要来确定自己看那篇文章的项目搭建。
关于SSM
关于SSM,我想简单说的就是至少目前还是主流的,即使已经出现的Spring Boot + mybatis 至多与其并肩同行,要想取代,仍需一定的时间。当然我也会在至少取代之前给大家介绍Spring Boot框架搭建
开始搭建
首先声明一下这次需要搭建的架构是单项目结构,使用的工具为eclipse
本次将从零开始,即从刚安装好的eclipse环境开始
配置JDK*
如果已经添加,可以跳过此步骤
这是配置项的入口,一定要记好哦,以后很多配置项基本都从这里进的
找到java -> Intalled JREs 匹配你当前环境的JDK版本
添加tomcat*
如果已经添加,可以跳过此步骤
apache下的tomcat,根据你实际的版本进行选择,即可next
接下来就需要选择tomcat路径了
接下来选择需要部署的项目,我们无项目可部署,跳过。
等待创建,即可完成
配置maven*
如果已经添加,可以跳过此步骤
同样还是在配置窗口下找到maven下的Installations配置maven安装路径,添加一个自己安装的maven
选择maven安装路径
使用新添加的maven再apply
然后再User Setting选项也是需要改的
就是setting.xml的路径,它会根据这个文件自动匹配本地仓库的路径
选择manve根目录下的conf下的setting.xml即可
最后apply完就可以close了
创建项目
如果你前面的工作都准备好了,那么接下来我们就要开始搭建项目了
这里要创建的项目肯定是maven工程
这里用maven创建web项目,我这边使用官方提供的架构来创建:
所以下一步直接next
找到带有webapp字样的架构,注意一定是这个
接下来输入坐标,即包名和项目名称
解决项目初始化的一系列问题
引入tomcat 的JAR包
创建完成后,我们的项目遭到了报错,这是因为没有tomcat运行时的jar包。
首先右键点击项目,选择属性选项:
这个是项目配置项的入口,也一定要记住哦
找到build Path 下添加library
即可
这时候项目就不报错了
匹配JRE 版本
但是出现如下警告:
也就是JRE的版本不匹配
这时我们需要添加一个maven-compile-plugin插件
我们可以通过maven repository官网找到这个插件的具体配置项,在项目中的pom.xml添加
最新的版本已经到3.8。可以根据本地仓库现有的情况选择
注意不是在dependency,要放在plugins下面哦!!
除此之外还有添加<configuration>
配置哦
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF8</encoding>
</configuration>
</plugin>
最后还需要update一下maven才会生效哦
右键点击项目,找到maven进行update
弹出的对话框,直接选择OK即可
补全maven项目结构
项目已经有了java 和 source缺少了一个test/sources
接下来我们将它补全
添加一个source folder
名字一定要是这个
然后需要配置项目输出的文件
这两个文件夹也是需要匹配的
选择编辑一下
有可能还要再选择一下,将contain test resources 改为yes即可
配置webapp输出目录
还是在项目的配置路径里,找到Deployment Assembly这里可以看到它默认根目录指向的不是webapp目录,而是webContent,但是按照maven项目的规范,我们需要将它改为webapp目录
将WebContent删除掉,再添加,选择Folder
找到webapp目录进行finish
即可
升级动态web 3.0
这里我们看到该项目的动态web版本还是在2.3,这里我们需要更高的版本
但是你选择不了
解决办法是把这个√去掉来apply一次
在把这个选中,再进行apply一次
这里就是我们的web.xml
但是这里还是2.3版本的,那是因为我们用官方默认创建的maven工程比较旧,还是2.3版本的
这里只需要改成3.1约束即可
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" metadata-complete="true">
<display-name>Archetype Created Web Application</display-name>
</web-app>
修改项目编码
还是在项目的配置窗口,把原来的GBK改为UTF8即可
启动web项目
把上面的一系列问题完成后就可以启动项目运行了
首先先进行项目发布 add and remove
把项目弄过去,Finish
一般需要先进行clean操作,保证最新同步
在进行启动 debug 或 run
或者直接使用Run on Server方式也行!
好了,到这里,maven项目在本地tomcat已经可以运行了
整合SSM
目录结构和整合思路
目录结构
- java Sources
- bean 实体包
- constanst 常量包
- dao
- web 控制器、拦截器等
- service
- java Resource
- config
- mapper mybatis的实体与表映射文件
- properties 属性配置文件
在config目录下,我们将SSM整合的配置拆分,这样做的好处在于方面日后扩展,也方面维护,就不至于一个配置文件里写了一堆东西
- applicationContext: 总配置文件、
- applicationContext-service: 给service的配置文件
- applicationContext-dao: 给dao层的配置文件
- applicationContext-web: 给web层的配置文件
- mybatis-config: mybatis总配置文件
整合思路
基于这样的结构,我们整合的思路也是分开来的,首先先是在web层,这一层配置啥呢?显然就和spring mvc有关了,就是做spring-mvc相关配置。
在service层呢?就可能是根据实际需要来配置了,但是最基础的,肯定是需要有spring Aop事务处理方面的配置
在dao层呢?很显然就是和数据库连接有关的配置了,并且让它找到mybatis总配置文件
除此之外,为了能够让spring注解注入,每一层都需要包扫描配置
最后就是需要将这些配置文件整合起来,统一在spring总配置文件里导入。
最后在web.xml引入spring和spring mvc并让它找到总配置文件即可了。
引入依赖
在做以上一切工作之前,先要做的那就是引入SSM依赖,这里我就根据我实际本地仓库来引入,已经引入了SSM所有必要的依赖,关于版本的问题,可以自行上maven repository官网去找就可以了。
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.3.5.Final</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.11</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.11</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.25</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.7</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.7</version>
</dependency>
如果你是新来的,这里肯定需要一点时间,因为要去官网下载,如果本地仓库就有,那就很快了,引入完成后,就可以在Maven Dependencies看到所有引入的必须包了:
分层配置
web层配置
web 层的配置主要是spring mvc前端控制器所需要的配置项,其中必要的包括@Controller注解注入配置,@RequestMapper的注解驱动,视图解析器,有可能需要的是参数校验器,或者拦截器以及文件上传配置等…
这里一一给大家列举:
文件约束
首先是xml约束头,需要有context和mvc约束即可
<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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
</beans>
在这里,eclipse有可能会因为找不到约束报错(需要联网去找),鉴于如果要根治这个问题有点麻烦,最简单的办法就是剪切一下约束头,在粘贴回去即可。
必要配置
接下来要配的是,首先要让前端控制器找到有@Controller注解的类,这个实现依赖于spring的依赖注入的特性,配置如下:
<context:component-scan base-package="com.edu.scnu.web.controller" />
其中base-package属性就是Controller类的包位置
接下来要让@RequestMapping这样的注解生效,需要开启spring mvc的注解驱动
<mvc:annotation-driven validator="validator"/>
其中validator是用于指定前端参数校验器使用哪种类来处理,如果只使用spring mvc自带的参数校验器可以忽略这个属性
如果指定了,就需要加上参数校验器的bean对象配置:
这里使用Hibernate的Validator
<!-- 注册校验器 -->
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="providerClass" value="org.hibernate.validator.HibernateValidator"></property>
</bean>
再下来,为了让spring mvc能够直接访问静态资源而不被前端控制器处理,加上允许访问静态资源的配置
<!-- 允许对静态资源文件的访问 -->
<mvc:default-servlet-handler/>
你也可使用如下配置手动指定静态资源的位置
<!-- 允许对静态资源文件的访问 -->
<mvc:resources mapping="/static/**" location="/static/" cache-period="3600"/>
其中cache-period属性就是用于设定缓存期限的。
接下来是spring mvc的视图解析器了,这里使用的是默认的视图解析器,你也可以整合freemarker,具体就去找相关资料看看吧。
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
文件上传解析器
接下来是补充的,只有你需要的时候再来配也不迟,一个是文件上传解析器:
<!-- 上传图片配置 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
拦截器配置
还有可能的是,拦截器的配置
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/login/**"/>
<mvc:exclude-mapping path="/assets/**"/>
<bean class="com.edu.scnu.web.interceptor.SessionInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
service层配置
对于service 也就没有太多的配置了,需要的也就是@Service的注解依赖,以及事务@Transaction的注解依赖,这些都是Spring的功能了,这里只用注解配置事务,如果需要统一配置,请看我的Spring Aop事务的一篇文章。
约束头
<?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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
</beans>
必要配置
@Service 注解配置
<context:component-scan base-package="com.edu.scnu.service" />
事务注解配置
<tx:annotation-driven/>
dao层配置
在dao层,就是和mybatis整合相关的配置了,需要做的是给mybatis的SqlSessionFactory一个连接池,以及mybatis相关配置文件的路径。
还有就是mybatis找到Dao接口的包扫描工具也是在这里配的,因为它不是spring的默认的注解配置。
约束文件头
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
</beans>
c3p0连接池对象
这些配置项不是写死的,需要通过propertis文件引入,具体怎么来,这里存个疑问吧,在实际项目中也是分开的,不会在这个文件配置文件当中引入数据库properties文件的
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${datasource.driverClassName}"/>
<property name="jdbcUrl" value="${datasource.url}"/>
<property name="user" value="${datasource.username}"/>
<property name="password" value="${datasource.password}"/>
<property name="acquireIncrement" value="${c3p0.acquireIncrement}"/>
<property name="initialPoolSize" value="${c3p0.initialPoolSize}"/>
<property name="minPoolSize" value="${c3p0.minPoolSize}"/>
<property name="maxPoolSize" value="${c3p0.maxPoolSize}"/>
<property name="maxIdleTime" value="${c3p0.maxIdleTime}"/>
<property name="autoCommitOnClose" value="${c3p0.autoCommitOnClose}"/>
</bean>
整合mybatis
接下来就是要把这个连接池丢给mybatis来工作了,丢给谁呢?应该是SqlSessionFactory
,请记住它的名字哦~~~
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:config/spring/mybatis-config.xml" />
</bean>
其中configLocation就是我们所说的mybatis主配置文件的路径啦!
最后需要的就是配置包扫描工具类,让mybatis能找到Dao接口在哪里
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.edu.scnu.dao" />
</bean>
mybatis总配置文件
引入了mybatis总配置文件后,那么mybatis总配置文件要做什么呢?
首先还是把约束头找出来:
它的约束头还算简单
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
</configuration>
然后可以先占时这样吧,后面具体用到再来看。
总配置
以上三层均配置完成后,就需要将他们集成了,这里集成就统一在applicationContext文件中去:
使用的是import
标签
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<context:property-placeholder location="classpath:properties/*.properties" />
<import resource="applicationContext-*.xml"/>
</beans>
其中context:property-placeholder就是用来引入属性文件的,这样就可以顺便把数据库配置的属性文件给加进去了,除此之外,还可能需要日志相关的log4j属性文件。
db.properties
datasource.type=mysql
datasource.autoCommitOnClose=false
datasource.driverClassName=com.mysql.jdbc.Driver
datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
datasource.username=root
datasource.password=test
c3p0.acquireIncrement=3
c3p0.initialPoolSize=5
c3p0.idleConnectionTestPeriod=900
c3p0.minPoolSize=10
c3p0.maxPoolSize=25
c3p0.maxStatements=150
c3p0.maxIdleTime=1800
c3p0.autoCommitOnClose=true
log4j
log4j.rootLogger = DEBUG, INFO, STDOUT
log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender
log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout
log4j.appender.DEBUG.layout.ConversionPattern=[%d{MM/dd HH:mm}] %m%n
log4j.appender.STDOUT.layout.ConversionPattern=[%d{MM/dd HH:mm}] %m%n
log4j.logger.jdbc.sqlonly=DEBUG,STDOUT
log4j.logger.jdbc.sqltiming=OFF
log4j.logger.jdbc.audit=OFF
log4j.logger.jdbc.resultset=OFF
log4j.logger.jdbc.connection=OFF
log4j.logger.org.apache.ibatis=OFF
log4j.logger.org.apache.ibatis.jdbc.ScriptRunner=DEBUG
log4j.logger.java.sql.Connection=OFF
log4j.logger.java.sql.Statement=OFF
log4j.logger.java.sql.PreparedStatement=OFF
log4j.logger.com.google=ERROR
log4j.logger.net.rubyeye=ERROR
log4j.logger.org.mybatis.example.BlogMapper=TRACE
那么apache的log4j类怎么知道我们这个log4j藏在peoperties目录下呢?这里也存个疑哈
web.xml配置,终极
上面做了那么多工作,但是这一步不做,一切都白搭,可想而知,原生的Servlet走它自己的流程,凭什么跟你spring spring mvc有关系?
所以需要web.xml的终极配置
在web-app 3.1的约束标准,是有标签先后顺序规范的,这里也将按照这个顺序来走。
context-param
首先配置的是context-param,这里有两个参数需要配置的,一个就是所有的spring相关的xml文件位置,另外一个就是log4j属性文件的位置了
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:config/spring/applicationContext*.xml</param-value>
</context-param>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:properties/log4j.properties</param-value>
</context-param>
filter: POST参数乱码解决
那么接下来呢?filter有没有需要配置的地方呢?很显然就是字符编码过滤器啦,这个不用说,项目肯定需要
<!-- 解决POST提交乱码 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
listener spring监听器
需要两个,一个是spring-context的监听器,一个是spring提供的日志监听器
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
servlet spring mvc前端控制器
spring mvc以servlet形式存在(大神可以思考这么设计的用意),所有访问都只需要经过它,所以不能再使用其他的servlet了。
这里只经过控制器请求,对于.jsp类似的请求我们当然不希望经过它,因此url-pattern使用的是 / 而不是 /*
在这里,我们再一次配置了spring mvc的contextConfigLocation,这里只需要引入总配置文件即可
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:config/spring/applicationContext.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
welcome-file-list 不解释
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
整合测试
spring mvc 测试
在Controller包下编写controller测试类,我们测试两种形式的访问请求相应
@Controller
@RequestMapping(IndexController.URL)
public class IndexController {
protected static final String URL = "/index";
@RequestMapping
public String index() {
return "system/index";
}
@RequestMapping(value="/delete", method=RequestMethod.GET)
@ResponseBody
public Map<String, Object> delete(Integer id) {
Map<String,Object> ret = new HashMap<String,Object>();
ret.put("success", 1);
ret.put("msg", "删除成功");
return ret;
}
}
添加页面,同时添加一些必要的css和js,测试静态文件是否能够引入成功
在index.jsp中,我们通过原生的pageContext来引入:
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath }/style/reset.css">
<script src="${pageContext.request.contextPath }/js/jquery.js"></script>
对于web层的测试,我们就需要run on Service来测了
启动项目后,只需要后加/index即可访问了
即使你没我那么顺利,在操作过程中失败了,任何404 500,控制台都会打印出详细的log信息,总比之前摸索着来定位好多了。
再看json数据,也是可以返回的
当然这里要注意,spring 升级到4.x + 版本以后,spring mvc 的@ResponseBody就跟不上了,就不能用上面这种方式直接返回对象了。如果你测试报错了,可能是因为版本问题。
mybatis 测试
对于mybatis的测试,为了简单起见,不需要从页面端开始,可以编写单元测试类,主要是看数据库是否连接成功,并且sql语句是否能得到执行
首先编写测试的Dao类
import java.util.Map;
public interface TestDao {
Map<String, Object> testQuery();
}
mapper配置
再编写对应的mapper
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.edu.scnu.dao.TestDao">
<select id="testQuery" resultType="java.util.Map">
SELECT CURRENT_DATE() AS `current_date` FROM DUAL
</select>
</mapper>
mybatis主配置文件配置
因此需要在mybatis主配置文件中加以配置,得到映射
这里就顺便配置一个,类型别名的配置
<configuration>
<typeAliases>
<package name="com.edu.scnu.bean"/>
</typeAliases>
<mappers>
<mapper resource="mapper/testMapper.xml"></mapper>
</mappers>
</configuration>
测试类编写
这里使用spring-test包的junit测试
由于没有web.xml注入,这里的spring-context使用@ContextConfiguration注解注入
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:config/spring/applicationContext.xml")
public class TestDaoTest {
@Autowired
private TestDao testDao;
Logger logger = Logger.getLogger(TestDaoTest.class);
@Before
public void before() {
// 配置log4j的文件位置 默认从项目的根目录开始的
PropertyConfigurator.configure("src/main/resources/properties/log4j.properties");
}
@Test
public void testTest() {
Map<String, Object> map = testDao.testQuery();
logger.info("### current_date: " + map.get("current_date"));
}
}
开始测试
提示错误
是真的properties没有引入进来吗,显然不是,不然之前在测试spring mvc的时候就不会启动成功的
那很有可能的问题就是,test包下,找不到properties文件了
因此这里的解决方式是将main/resources/properties目录copy到test/resouces下,测试是否能访问成功
运行成功,并打印sql,就算完成啦!!!
结束及后续
那么到这里,完整的SSM的maven工程在eclipse即可顺畅运行了,总的来说还算是经历了一番折腾。但最终还是可以整出个项目了!!!
那么使用IDEA的小伙伴呢?在这里先思考一下,这一篇那么多流程过程中,如果非要说用eclipse和IDEA有什么不同,那会是什么呢?我想框架的搭建肯定是一样的,只是要配置maven在tomcat运行过程的一些配置肯定是不一样。
因此,接下来的文章中呢,我就不会把框架的搭建,比如配置文件详解这个部分,代码编写的这个部分就不细节讲了,需要的我就只是注明,回看本文吧。
接下来,也会和展示一下使用分布式、微服务架构来搭SSM,本文的搭建,将web和service分开,也是为了接下来的扩展。这里说太多可能也无济于事,留个悬念,期待下次的扩展给大家感受感受