最近在学习ssm框架,由于不知名的缘由,一个小小的框架居然花了我四五天的时间,期间遇到了近百个各类各样的错误,也正是因为这些错误,让我对ssm框架有了进一步的认识,谨做略记,但愿利于他人,仅供和我同样刚入门的新手参考,一块儿学习。理论的东西就很少少了,直接上配置吧。css
这个就很少说了,直接百度,各类博客有不少,写得都很详细,可是要注意版本的问题,我怀疑以前我遇到的各类问题都和引入的spring之类的版本冲突有关,最好找发布时间不长的教程。
html
先看看整个项目的目录吧,目录结构以下图:
java
须要注意的就是:建立出来以后,目录结构里的main>java,test>java,test>resources都须要本身建立,能够直接在相应的文件夹上右键建立,也能够在file>project structure下建立,建立完directory以后须要右键mark as相应的文件夹。mysql
还有就是会遇到在src>main>java下建立同级包的时候会默认合并路径,没法在一个包下建立同级包,按下图操做,取消勾选Hide Empty Middle Packages便可。web
引入maven依赖须要注意的就是版本的统一管理,相关的包引入的版本最好能一致,保证兼容,将版本写在<properties></properties>里,而后再统一引用,既方便管理,又能避免不少问题,有点封装的意思。我折腾了好久极可能就是版本是随便选择的,因此致使各类问题。引入的依赖以下:spring
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>demon</groupId> <artifactId>demon</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>demon Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <spring.version>4.0.2.RELEASE</spring.version> <mybatis.version>3.2.6</mybatis.version> <slf4j.version>1.7.7</slf4j.version> <log4j.version>1.2.17</log4j.version> </properties> <dependencies> <!--junit单元测试--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <!--spring相关的包--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-oxm</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <!--mybatis相关的包--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>${mybatis.version}</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.2.3</version> </dependency> <!--java ee--> <dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>7.0</version> </dependency> <!--mysql--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.39</version> </dependency> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!--日志管理的包--> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>${log4j.version}</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.1.41</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.9.13</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>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.9</version> </dependency> <dependency> <groupId>com.esotericsoftware.reflectasm</groupId> <artifactId>reflectasm</artifactId> <version>1.09</version> </dependency> <!--hibernate验证框架--> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.2.4.Final</version> </dependency> </dependencies> <build> <finalName>demon</finalName> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>*.xml</include> <include>*.properties</include> </includes> </resource> </resources> </build> </project>
以上就是maven依赖的包,<build></build>标签里的内容是将resources目录和java目录下的文件也加到项目路径,由于我启动项目出现了mapper.xml,spring-mvc.xml文件没法加载的状况。sql
create table `test`.`user`( `username` varchar(25) NOT NULL COMMENT `用户名`, `password` varchar(25) NOT NULL COMMENT `密码`, PRIMARYKEY(`username`) )ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT `用户信息表`;
在po包下建立UserPo.java文件,记得加上构造方法,以及默认的构造方法,代码以下:
数据库
package com.demon.user.po; /** * @author zhulongkun20@163.com * @date 2018/3/21 14:22 */ public class UserPo { private String username; private String password; public UserPo(String username, String password) { this.username = username; this.password = password; } public UserPo() { } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String toString() { return "===== UserPo : [ username : " + username + ", password : " + password + " ] ====="; } }
建立UserDao.java接口,是接口,不是类!放与数据库操做相关的方法:apache
package com.demon.user.dao; import com.demon.user.po.UserPo; import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Repository; /** * @author zhulongkun20@163.com * @date 2018/3/21 14:23 */ @Repository public interface UserDao { UserPo selectUserByUsername(@Param("username") String username); }
记得给接口加上@Repository注解。json
建立UserService.java,这个也是接口,不是方法,里面放与业务逻辑。
package com.demon.user.service; import com.demon.user.po.UserPo; /** * @author zhulongkun20@163.com * @date 2018/3/21 14:26 */ public interface UserService { public UserPo selectUserByUsername(String username); }
建立UserServiceImpl类,实现UserService接口,记得加上@Service注解,否则spring配置文件不能建立bean。
package com.demon.user.service; import com.demon.user.dao.UserDao; import com.demon.user.po.UserPo; import org.springframework.stereotype.Service; import javax.annotation.Resource; /** * @author zhulongkun20@163.com * @date 2018/3/21 14:27 */ @Service public class UserSeviceImpl implements UserService { @Resource private UserDao userDao; public UserPo selectUserByUsername(String username) { return userDao.selectUserByUsername(username); } }
记得给类加上@Controller注解,还有@RequestMapping("")注解,否则会报错,找不到controller。
package com.demon.user.controller; import com.demon.user.po.UserPo; import com.demon.user.service.UserService; import org.apache.log4j.Logger; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; /** * @author zhulongkun20@163.com * @date 2018/3/21 15:34 */ @Controller @RequestMapping("/user") public class UserController { private static Logger logger = Logger.getLogger(UserController.class); @Resource private UserService userService; @RequestMapping("/showUser.do") public ModelAndView showUser(HttpServletRequest request) { String username = request.getParameter("username"); UserPo userPo = userService.selectUserByUsername(username); if (userPo != null) { logger.info("====== request success."); request.setAttribute("username", username); return new ModelAndView("success", "message", username); } else { logger.info("====== request failed."); return new ModelAndView("failed", "message", "request failed, try again!"); } } }
<?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.demon.user.dao.UserDao"> <resultMap id="BaseResultMap" type="com.demon.user.po.UserPo"> <result column="username" property="username" jdbcType="VARCHAR"/> <result column="password" property="password" jdbcType="VARCHAR"/> </resultMap> <select id="selectUserByUsername" resultMap="BaseResultMap" parameterType="java.lang.String"> SELECT username, password FROM user WHERE username = #{username, jdbcType=VARCHAR} </select> </mapper>
注意命名空间namespace的指向的包。
在src>main>resources下建立log4j.properties文件,主要是log4j的配置,记得建立一个存放日志的file,更改日志输出的目标文件。
# 配置 log4j.rootLogger=debug,stdout,D,E ### 输出信息到控制抬 ### log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.out log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n ### 输出DEBUG 级别以上的日志到文件F://logs/debug.log ### log4j.appender.D=org.apache.log4j.FileAppender log4j.appender.D.File=F:/coquetry-demon/logs/debug.log log4j.appender.D.Append=true log4j.appender.D.Threshold=DEBUG log4j.appender.D.layout=org.apache.log4j.PatternLayout log4j.appender.D.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n ### 输出ERROR 级别以上的日志到文件F://logs/error.log ### log4j.appender.E=org.apache.log4j.FileAppender log4j.appender.E.File=F:/coquetry-demon/logs/error.log log4j.appender.E.Append=true log4j.appender.E.Threshold=ERROR log4j.appender.E.layout=org.apache.log4j.PatternLayout log4j.appender.E.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%
将数据库的用户名,密码等单独放到jdbc.properties文件中,方便项目的移植和管理。
database.driver=com.mysql.jdbc.Driver database.url=jdbc:mysql://localhost:3306/你的数据库名 database.username=你的数据库用户名 database.password=你的数据库密码
建立spring-mybatis.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <context:component-scan base-package="com.demon.user"/> <context:property-placeholder location="classpath:/jdbc.properties"/> <!--connect to database--> <bean id="jdbcDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="${database.driver}"/> <property name="url" value="${database.url}"/> <property name="username" value="${database.username}"/> <property name="password" value="${database.password}"/> </bean> <!--spring and mybatis configuration here--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="jdbcDataSource"/> <property name="mapperLocations" value="classpath:com/demon/user/mapper/*.xml"/> </bean> <!--the package name where contains dao, enable auto scan--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.demon.user.dao"/> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> </bean> <!--transaction manager--> <!-- <tx:annotation-driven transaction-manager="transactionManager"/> --> <!--add transaction operation--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="jdbcDataSource"/> </bean> </beans>
建立spring-mvc.xml文件,配置spring mvc:
<?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-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> <context:component-scan base-package="com.demon.user.controller"/> <mvc:annotation-driven/> <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>text/html;charset=UTF-8</value> </list> </property> </bean> <!-- 启动SpringMVC的注解功能,完成请求和注解POJO的映射 --> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <list> <ref bean="mappingJacksonHttpMessageConverter"/> <!-- JSON转换器 --> </list> </property> </bean> <!-- 定义跳转的文件的先后缀 ,视图模式配置--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> <!--使用默认的Servlet来响应静态文件--> <mvc:default-servlet-handler/> <!-- 配置文件上传,若是没有使用文件上传能够不用配置,固然若是不配,那么配置文件中也没必要引入上传组件包 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 默认编码 --> <property name="defaultEncoding" value="utf-8"/> <!-- 文件大小最大值 --> <property name="maxUploadSize" value="10485760000"/> <!-- 内存中的最大值 --> <property name="maxInMemorySize" value="40960"/> </bean> </beans>
这个就是要注意<servlet-mapping></servlet-mapping>拦截器的配置,这里会产生不少错误。
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <session-config> <session-timeout>60</session-timeout> </session-config> <filter> <filter-name>encode</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>encode</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <context-param> <param-name>log4jConfigLocation</param-name> <param-value>classpath:log4j.properties</param-value> </context-param> <listener> <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mybatis.xml</param-value> </context-param> <!-- Spring监听器 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 防止Spring内存溢出监听器 --> <listener> <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class> </listener> <!--RequestContextListener将Spring容器与Web容器结合的更加密切。这是可选配置--> <listener> <listener-class> org.springframework.web.context.request.RequestContextListener </listener-class> </listener> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> </web-app>
到这里三大框架整合完毕了,主要是配置文件容易出错。
在test>java下建一个包,而后创建一个MybatisTest.java的测试类,测试一下能不能从数据库里读出信息。
package com.demon.test; import com.demon.user.po.UserPo; import com.demon.user.service.UserService; import org.apache.log4j.Logger; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import javax.annotation.Resource; /** * @author zhulongkun20@163.com * @date 2018/3/21 15:00 */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:spring-mvc.xml", "classpath:spring-mybatis.xml"}) public class MybatisTest { private static Logger logger = Logger.getLogger(MybatisTest.class); @Resource private UserService userService; @Test public void selectUserByUsernameTest() { String username = "admin1"; UserPo userPo = userService.selectUserByUsername(username); if (userPo != null) { logger.info("======= Test Result =======\n"); logger.info(userPo.toString()); logger.info("======= Result End =======\n"); } } }
若是能在日志里找到输出信息,那恭喜,mybatis没问题,若是有错,那就查日志,而后去各类百度吧,好事多磨,放平心态。。
简单的测试页面:
index.jsp:
<%-- Created by IntelliJ IDEA. User: zhulongkun Date: 2018/3/21 Time: 13:25 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>欢迎访问</title> </head> <body> <% String path = request.getContextPath(); %> <div align="center"> <form action="<%=path%>/user/showUser.do" method="post"> <p>欢迎你的访问, 请输入我的信息</p> <hr/> <p> <label> <input type="text" name="username" width="300px" height="45px"/> </label> </p> <p> <input type="submit" value="提交" width="100px" height="45px"/></p> </form> </div> </body> </html>
请求成功则跳转到success.jsp:
<%@ page import="com.demon.user.po.UserPo" %><%-- Created by IntelliJ IDEA. User: zhulongkun Date: 2018/3/21 Time: 15:44 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>request success</title> </head> <body> <% String username = (String) request.getAttribute("username"); %> <div align="center"> <p> <h1>welcome <%=username%> !</h1 </div> </body> </html>
若是请求失败,则跳转到failed.jsp:
<%-- Created by IntelliJ IDEA. User: zhulongkun Date: 2018/3/21 Time: 15:45 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>request failed</title> </head> <body> <div align="center"> <h1>request failed, try again, please.</h1> </div> </body> </html>
看似简单,却折腾了几天,不少次感到绝望,可是不修bug,人生还有什么意义?要不断的找缘由,不断地改错,才能不断地进步,也算是一点心得吧!
以上です!