1 SSM框架整合介绍
1.1整合步骤
创建项目,添加jar包(核心是哪几个)
创建包,创建实体与Mapper(mybatise生成器使用,mybatise流程)
添加连接数据库的properties文件
添加log4j配置文件
添加spring配置文件(重点是配置的内容有哪些)
添加springmvc配置文件(内容)
修改web.xml文件(tomcat执行流程,启动spring流程,启动springmvc流程)
1.2 jar包
27个
spring(8)
springmvc(2)
servlet(1)
servlet-api.jar
mybatis(12)
aspectjweaver(1)
jstl(2)
mysql(1)
2 搭建整合环境
2.1创建表
CREATE TABLE `users` (
`userid` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(30) NOT NULL,
`userpwd` varchar(30) NOT NULL,
PRIMARY KEY (`userid`),
UNIQUE KEY `username_uk` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2.2搭建环境
2.2.1 创建项目并添加 jar 包
2.2.2 创建包,创建实体类与 Mapper
使用mybatis提供的逆向工程,修改.xml指定表名字,运行GenerateSqlmap,得到表对应的实体类、mapper类.复制到ssmdemo对应包中。
3 配置 SSM 整合
3.1添加数据库与 log4j 配置文件
3.1.1 添加连接数据的 properties 文件
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm
jdbc.username=root
jdbc.password=123
3.1.2 添加 log4j 配置文件
log4j.rootLogger=info,console
### appender.console输出到控制台 ###
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=<%d> %5p (%F:%L) [%t] (%c) - %m%n
log4j.appender.console.Target=System.out
### appender.logfile输出到日志文件 ###
log4j.appender.logfile=org.apache.log4j.RollingFileAppender
log4j.appender.logfile.File=SysLog.log
log4j.appender.logfile.MaxFileSize=500KB
log4j.appender.logfile.MaxBackupIndex=7
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=<%d> %p (%F:%L) [%t] %c - %m%n
3.2添加 Spring 配置文件
在 SSM 框架整合时为了能够清晰的对 Spring 配置项进行管理,我们可以采用“分而治 之”的方式来定义 Spring 配置文件。将 Spring 配置文件分解成三个配置文件,在不同的配 置文件中配置不同的内容。
applicationContext-dao.xml 该配置文件的作用是用来配置与 Mybatis 框架整合。
applicationContext-trans.xml 该配置文件的作用是用来配置 Spring 声明式事务管理。
applicationContext-service.xml 该配置文件的作用是用来配置注解扫描以及其他的 Spring 配置。
3.2.1 配置整合 Mybatis
applicationContext-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: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">
<!--配置解析 Properties 文件的工具类-->
<context:property-placeholder location="classpath:db.properties"/>
<!--配置数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--配置 SqlSessionFactory-->
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="typeAliasesPackage" value="com.bjsxt.pojo"/>
</bean>
<!--配置 MapperScannerConfigurer-->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.bjsxt.mapper"/>
</bean>
</beans>
3.2.2 配置声明式事务管理
applicationContext-trans.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"
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">
<import resource="applicationContext-dao.xml"/>
<!--配置事务管理器的切面-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--配置事务属性-->
<tx:advice id="myAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="modify*" propagation="REQUIRED"/>
<tx:method name="drop*" propagation="REQUIRED"/>
<tx:method name="userLogin" propagation="REQUIRED"/>
<tx:method name="find*" read-only="true"/>
</tx:attributes>
</tx:advice>
<!--配置切点-->
<aop:config>
<aop:pointcut id="myPointcut" expression="execution(* com.bjsxt.service.*.*(..))"/>
<aop:advisor advice-ref="myAdvice" pointcut-ref="myPointcut"/>
</aop:config>
</beans>
3.2.3 配置注解扫描
applicationContext-service.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置注解扫描-->
<context:component-scan base-package="com.bjsxt.service,com.bjsxt.aop"/>
</beans>
3.3配置 SpringMVC
springmvc.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.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">
<!--配置注解扫描-->
<context:component-scan base-package="com.bjsxt.web.controller,com.bjsxt.exception"/>
<!--配置注解驱动-->
<mvc:annotation-driven/>
<!--配置视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--配置静态资源映射器-->
<mvc:resources mapping="/js/**" location="/WEB-INF/js/"/>
<mvc:resources mapping="/img/**" location="/WEB-INF/img/"/>
<mvc:resources mapping="/css/**" location="/WEB-INF/css/"/>
<!--配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/page/login"/>
<mvc:exclude-mapping path="/page/error"/>
<mvc:exclude-mapping path="/user/userLogin"/>
<bean class="com.bjsxt.intercepter.LoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>
3.4Spring 与 SpringMVC 父子容器问题
在 Spring 与 Springmvc 同时使用时,Spring 的 ContextLoaderListener 会创建的 SpringIOC 容器,SpringMVC 的 DispatcherServlet 会创建 SpringMVC 的 IOC 容器。SpringMVC 会将 SpringIOC 容器设置为父容器。
父容器对子容器是可见的,所以在子容器中可以访问父容器的 Bean 对象,而子容器对 父容器不可见的,所以在父容器中无法获取子容器的 Bean 对象。
注解扫描时需要注意:
如果在 SpringMVC 的配置文件中扫描所有注解,会出现声明式事务失效。
因为 Spring 声明式事务管理的切面位于 Spring 的 IOC 容器,而子容器对父容器不可见,
所以事务管理器 的切面无法对 SpringIOC 容器中的 Bean 对象实现事务控制。
如果在 Spring 的配置文件中扫描所有注解,会出现无法找到控制器而报 404 的异常。
因为 HandleMapping 在根据 URI 查找控制器时,只会去 SpringMVC 的 IOC 容器中查找控制器, 而在 SpringMVC 的 IOC 容器并没有控制器对象,所以会出现 404 的异常。
正确使用方式: 在 SpringMVC 的配置文件中扫描@Controller 注解,
在 Spring 的配置文件中扫描除了 @Controller 以外的其他注解。
在 SpringMVC 的控制器可以注入 SpringIOC 容器中的 Bean 对 象,因为父容器对子容器是可见的。
3.5配置 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
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_4_0.xsd"
version="4.0">
<!--指定Spring配置文件的位置及名称-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext-*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--配置 SpringMVC 的前端控制器-->
<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:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 配置字符编码过滤器-->
<filter>
<filter-name>encodingFilter</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>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
经运行可成功访问web下的index.jsp(yuWEB-INF同级)
4 实现用户登录业务
需求:实现用户登录业务,同时记录用户的登录日志。登录日志要求记录用户名、登录 时间以及登录的 IP 地址。
4.1实现用户登录
4.1.1 创建业务层
package com.bjsxt.service;
import com.bjsxt.pojo.Users;
public interface UsersService {
Users userLogin(Users users);
}
package com.bjsxt.service.impl;
import com.bjsxt.exception.UserNotFoundException;
import com.bjsxt.mapper.UsersMapper;
import com.bjsxt.pojo.Users;
import com.bjsxt.pojo.UsersExample;
import com.bjsxt.service.UsersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UsersServiceImpl implements UsersService {
@Autowired
private UsersMapper usersMapper;
@Override
public Users userLogin(Users users) {
UsersExample usersExample = new UsersExample();
UsersExample.Criteria criteria = usersExample.createCriteria();
criteria.andUsernameEqualTo(users.getUsername());
criteria.andUserpwdEqualTo(users.getUserpwd());
List<Users> list = this.usersMapper.selectByExample(usersExample);
if(list == null || list.size() <= 0) {
throw new UserNotFoundException("用户名或密码有误!");
}
return list.get(0);
}
}
4.1.2 创建自定义异常
package com.bjsxt.exception;
public class UserNotFoundException extends RuntimeException {
public UserNotFoundException() {
}
public UserNotFoundException(String s) {
super(s);
}
public UserNotFoundException(String s, Throwable throwable) {
super(s, throwable);
}
}
4.1.3 创建用户登录控制器
package com.bjsxt.web.controller;
import com.bjsxt.pojo.Users;
import com.bjsxt.pojo.UsersExt;
import com.bjsxt.service.UsersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@Controller
@RequestMapping("/user")
public class UsersController {
@Autowired
private UsersService usersService;
@RequestMapping("/userLogin")
public String userLogin(UsersExt users, HttpSession session, HttpServletRequest request){
users.setIp(request.getRemoteAddr());
Users user = this.usersService.userLogin(users);
session.setAttribute("user",user);
return "redirect:/page/index";
}
}
4.1.4 全局异常处理器
package com.bjsxt.exception;
import com.sun.org.apache.xpath.internal.operations.Mod;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import java.util.Map;
@ControllerAdvice
public class GlobalExceptionController {
@ExceptionHandler({com.bjsxt.exception.UserNotFoundException.class})
public String userNotFoundExceptionHandler(Exception e, Model model) {
model.addAttribute("msg",e.getMessage());
return "login";
}
/**
* 控制器中出现不关心的异常就跳转到error页面
* @param e
* @return
*/
@ExceptionHandler({java.lang.Exception.class})
public String userNotFoundExceptionHandler(Exception e) {
return "redirect:/page/error";
}
}
别忘了配置扫描exception包!否则不执行。
再springmvc配置文件中加上注解扫描。因为@ControllerAdvice属于springmvc的jar包(破折号)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: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">
<!--配置注解扫描-->
<context:component-scan base-package="com.bjsxt.web.controller,com.bjsxt.exception"/>
<!--配置注解驱动-->
<mvc:annotation-driven/>
<!--配置视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".ajsp"/>
</bean>
<!--配置静态资源映射器-->
<mvc:resources mapping="/js/**" location="/WEB-INF/js/"/>
<mvc:resources mapping="/img/**" location="/WEB-INF/img/"/>
<mvc:resources mapping="/css/**" location="/WEB-INF/css/"/>
<!--配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/page/login"/>
<mvc:exclude-mapping path="/page/error"/>
<mvc:exclude-mapping path="/user/userLogin"/>
<bean class="com.bjsxt.intercepter.LoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>
4.1.5 创建用户登录页面
<%--
Created by IntelliJ IDEA.
User: HP
Date: 2021/1/18
Time: 21:45
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${msg}
<form action="/user/userLogin" method="post">
登录名:<input type="text" name="username"/><br/>
密码:<input type="password" name="userpwd"/><br/>
<input type="submit" value="OK"/>
</form>
</body>
</html>
4.1.6 创建异常提示页面
<%--
Created by IntelliJ IDEA.
User: HP
Date: 2021/1/18
Time: 21:46
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
出错了!请求与管理员联系:oldlu@bjsxt.com
</body>
</html>
4.1.7 创建页面跳转控制器
package com.bjsxt.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class PageController {
/**
* 首页
*/
@RequestMapping("/")
public String showIndex(){
return "index";
}
/**
* 页面跳转
*/
@RequestMapping("/page/{page}")
public String showPage(@PathVariable String page) {
return page;
}
}
问题:
用户没有登陆也能访问index.jsp(首页)
希望只有登录的用户才能访问index.jsp,如果没有登陆就跳转到/page/login,login.jsp中
解决:
使用拦截器,拦截除了登录页面请求、登录请求之外的所有请求,拿出请求数据中的session,如果由user信息那么放行该请求,
否则重定向到/page/login
4.1.8 创建判断用户是否登录的拦截器
package com.bjsxt.intercepter;
import com.bjsxt.pojo.Users;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
Users user = (Users) session.getAttribute("user");
if(user == null || user.getUsername().length() <= 0) {
response.sendRedirect("/page/login");
return false;
}
return true;
}
}
4.1.9 配置拦截器
别忘了再springmvc中配置拦截的方法,方形的方法!否则不执行。
<!--配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/page/login"/>
<mvc:exclude-mapping path="/page/error"/>
<mvc:exclude-mapping path="/user/userLogin"/>
<bean class="com.bjsxt.intercepter.LoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
完成用户登录功能了。
当用户登录成功,那么像日志表中记录一条登录日志,否则不记录,抛出异常页面。
先要创建日志表
4.2记录用户登录日志
4.2.1 创建表
CREATE TABLE `logs` (
`logid` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(30) DEFAULT NULL,
`ip` varchar(30) DEFAULT NULL,
`logtime` date DEFAULT NULL,
PRIMARY KEY (`logid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
4.2.2 创建实体类与 Mapper
mybatis逆向工程,生成后复制着4个类到ssmdemo项目对应包中。
4.2.3 创建日志记录切面
package com.bjsxt.aop;
import com.bjsxt.mapper.LogsMapper;
import com.bjsxt.pojo.Logs;
import com.bjsxt.pojo.UsersExt;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
@Aspect
@Component
public class UsersLoginLogAOP {
@Autowired
private LogsMapper logsMapper;
@Pointcut("execution(* com.bjsxt.service.UsersService.userLogin(..))")
public void myPointcut(){
}
@AfterReturning("myPointcut()")
public void userLoginLog(JoinPoint joinPoint) {
Object[] args = joinPoint.getArgs();
UsersExt usersExt = (UsersExt)args[0];
Logs logs = new Logs();
logs.setIp(usersExt.getIp());
logs.setLogtime(new Date());
logs.setUsername(usersExt.getUsername());
this.logsMapper.insertSelective(logs);
}
}
Uses中没有ip信息,使用继承的方式增加ip
如果要再Users中加,要使用逆向工程重新生成四个类…不好!
4.2.4 创建 Users 扩展实体类
package com.bjsxt.pojo;
public class UsersExt extends Users {
private String ip;
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
}
4.2.5 修改控制器
package com.bjsxt.web.controller;
import com.bjsxt.pojo.Users;
import com.bjsxt.pojo.UsersExt;
import com.bjsxt.service.UsersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@Controller
@RequestMapping("/user")
public class UsersController {
@Autowired
private UsersService usersService;
@RequestMapping("/userLogin")
public String userLogin(UsersExt users, HttpSession session, HttpServletRequest request){
users.setIp(request.getRemoteAddr());
Users user = this.usersService.userLogin(users);
session.setAttribute("user",user);
return "redirect:/page/index";
}
}
4.2.6 配置切面
再spring中配置切面,不要忘了,否则增强的日志功能将不执行!!
注解扫描和代理对象配置
项目运行结果:
1 登录成功
输入admin,admin
2 登录失败
输入admin 1
3 未登录访问首页
换个浏览器输入
http://localhost:8080/
回车,重定向了!
4 原先登陆成功过的浏览器访问首页
完成ssm框架搭建!!
总结:
spring框架的包,aop,aspecj,weaver那个jar,配置aop,trans,
springmvc,exception,intercepter,controller配置
web.xml使用监听器,当tomcat创建ServletContext,监听器执行,从而拿到spring配置文件,启动spring框架,扫描包,创建对象,并管理。
使用servlet,tomcat加载web.xml中的servlet有一个别名springmvc,有一个DispatcherServlet全路径,有一个uri / 跟springmvc绑定,当来一个请求,tomcat就根据uri找对应的dispatecherservlet,内存里没有就创建,然后开启一个新的线程执行servlet的service方法。将uri与controller绑定,找到对应的方法,执行!!