该系列为imooc Spring从入门到进阶笔记,跟随课程加入自己见解,同时也为项目中碰到一些问题做了解答
本门课程是使用使用Spring+Mybatis+Servlet开发人员信息管理系统
1、课程介绍
案例
- 人员信息管理系统
前置条件
- Mybatis、Spring、Servlet
- Mysql
主要技术
- Servlet、Jsp
- Spring IOC、Spring AOP
- Mybatis
- Mybatis+Spring整合
课程开发环境
- 操作系统 Win7
- Web容器 Tomcat-8.5
- 数据库 Mysql-5.7
- 开发工具 IntelliJ IDEA
- Spring 4.0.2.RELEASE
- Mybatis 3.4.4
课程资料
项目结构
-
三层架构
- 持久层–Mybatis
- 表现层–Servlet+Jsp
- Spring–管理对象、切面处理
-
基于MVC模式
- 视图–Jsp
- 模型–JavaBean
- 控制器–Servlet+JavaBean
2、项目准备
2.1、数据库设计
2.2、SQL语句
drop database if exists sm;
create database sm;
use sm;
create table department(
id int primary key auto_increment,
name varchar(20) not null,
address varchar(100)
);
create table staff(
id int primary key auto_increment,
account varchar(20) not null,
password varchar(20) not null,
status varchar(10) not null,
did int,
name varchar(20),
sex char(2),
id_number char(18),
work_time datetime,
leave_time datetime,
born_date date,
info varchar(200)
);
create table log(
opr_time datetime not null,
type varchar(10) not null,
operator varchar(20) not null,
moudle varchar(20) not null,
operation varchar(20) not null,
result varchar(100) not null
);
alter table staff add constraint fk_staff_dep foreign key(did) references department(id);
2.3、项目搭建
sm– 父moudle
- 全局定义与组织
sm_service– 子moudle
- 持久层、业务层
- Mybatis依赖、Spring依赖
sm_web– 子moudle
- 表现层
- Servlet依赖
1.创建sm– 父moudle
sm– 父moudle不实现具体功能,故src目录可以删掉
- 在父moudel下创建sm_service– 子moudle
- 在父moudel下创建sm_web– 子moudle
使用Override User settings file前提是在该指定路径下有settings.xml配置文件
2.4、配置POM文件
sm– 父moudle
<properties>
<spring.version>4.0.2.RELEASE</spring.version>
</properties>
sm_service– 子moudle
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.44</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.4</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
</dependencies>
sm_web– 子moudle
<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">
<parent>
<artifactId>sm</artifactId>
<groupId>com.imooc</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>sm_web</artifactId>
<packaging>war</packaging>
<name>sm_web Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>com.imooc</groupId>
<artifactId>sm_service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
<build>
<finalName>sm_web</finalName>
</build>
</project>
2.5、导入素材中的静态文件(css、js、图片)
2.6、Spring全局配置
- Spring整合Mybatis
- Spring用来做对象管理的,在项目中所有与功能相关的对象,都应有Spring进行管理
- Mybatis用来做持久化操作,则必需管理若干个对象,比如:SqlSessionFactory、持久化操作对象(增删改查的功能对象)
- Spring整合Mybatis,就是把Mybatis原来管理的对象交给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"
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/context
http://www.springframework.org/schema/context/spring-context.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">
<!--Spring整合Mybatis-->
<!--配置数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/sm?useUnicode=true&characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
<!--Spring配置session工厂-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!--简化实体类类名,配置后不用再使用全称(包名+类名),只需类名-->
<property name="typeAliasesPackage" value="com.imooc.sm.entity"/>
</bean>
<!--Spring配置持久化对象-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.imooc.sm.dao" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
<!--以上配置完成了Spring对Mybatis配置,配置完成之后,将不再需要Mybatis的配置文件了,同时也把Mybatis原来管理的对象,交给了Spring进行管理-->
<!--声明式事物配置-->
<!--配置事物管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--配置通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--指定事物的属性,get/find/search等方法不使用事物进行封装-->
<tx:method name="get*" read-only="true"/>
<tx:method name="find*" read-only="true"/>
<tx:method name="search*" read-only="true"/>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!--植入的相关配置-->
<aop:config>
<!--配置切入点-->
<aop:pointcut id="pointcut" expression="execution(* com.imooc.sm.service.*.*(..))"/>
<!--定义通知器(通知器跟切面一样,也包括通知和切点)-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
</aop:config>
<!--完成声明式事物配置-->
<!--全局扫描-->
<!--开启注解扫描-->
<context:component-scan base-package="com.imooc.sm"/>
<!--开启AspectJ自动代理-->
<aop:aspectj-autoproxy/>
</beans>
2.7、工具类准备
工具类:指一个项目中,多个模块共同需要的功能,我们将其抽离出来专门放置在一个地方,其他模块需要的时候就去调用
目前项目各模块文件夹创建如图所示
2.7.1、编码过滤器
作为Web项目,所有模块都会去处理请求与响应,那么编码过滤器就是必须的,那么我们先实现工具类-编码过滤器
- sm_web模块>src>main>java>com.imooc.sm.global包下>新建EncodingFilter(编码过滤器)
package com.imooc.sm.global;
import javax.servlet.*;
import java.io.IOException;
public class EncodingFilter implements Filter {
private String encoding ="UTF-8";
public void init(FilterConfig filterConfig) throws ServletException {
if(filterConfig.getInitParameter("ENCODING")!=null)
encoding = filterConfig.getInitParameter("ENCODING");
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding(encoding);
servletResponse.setCharacterEncoding(encoding);
filterChain.doFilter(servletRequest,servletResponse);
}
public void destroy() {
encoding=null;
}
}
- 在sm_web模块中的web.xml配置过滤器
通过Maven模板生成的web项目中,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_3_1.xsd"
version="3.1">
<filter>
<filter-name>Encoding</filter-name>
<filter-class>com.imooc.sm.global.EncodingFilter</filter-class>
<init-param>
<param-name>ENCODING</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
2.7.2、核心控制器
为什么要有核心控制器
-
当用户向web容器发送请求时,web容器会根据请求的url,判断是否该用Servlet以及用哪个Servlet处理。判断完成后它会构造出Servlet对象然后进行初始化,之后再调用service方法对请求进行处理。
-
但是,Servlet对象由Web容器进行管理。service对象、dao对象(持久化操作对象)由IOC容器进行管理。Servlet对象处理用户请求时需要调用Service对象,根据IoC思想,你需要A对象我就自动帮你注入A对象,但是在这里是无法实现的。因为servlet对象不在IoC容器里(servlet对象不由IoC容器管理),所以没办法帮他注入需要的A对象,所以在Servlet对象无法使用spring_ioc进行Service对象的注入。
注意区分:
核心控制器
控制器指(图示中控制器1、2)
如何解决
- 解决:核心控制器。
- 用户发送请求到web容器,web容器将请求全部交给核心控制器(一个Servlet),核心控制器不做具体操作,只是判断该调用哪个控制器进行处理这次请求。
- 那么这些控制器也是一个对象,且是被我们自己写的核心控制器进行选择调用,所以可以将这些控制器对象放到IOC容器里。再从IOC容器里获取这些控制器对象。
- 也就是说,我接受用户的url,通过核心控制器解析之后判断是由哪个控制器来处理它,那么我就从IOC容器里把这个控制器的对象拿出来。因为控制器在ioc容器里,如果控制器需要调用service的一些功能,那么IOC容器自然可以帮他注入进来。
核心控制器干什么
- 解析url得到IOC容器里控制器的bean的名字
- 处理这一次请求匹配IOC容器里对应的控制器对应的方法。
(通过控制器的bean的名字在IOC容器中把这个控制器bean对象拿出来,然后再通过该控制器的方法名反射执行该方法。)
并不是说说有请求都交给核心控制器,是有一定规范的请求才交给核心控制器,比如说以后缀名进行规范
- sm_web模块>src>main>java>com.imooc.sm.global包下>新建DispatcherServlet(核心控制器)
package com.imooc.sm.global;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class DispatcherServlet extends GenericServlet {
private ApplicationContext context;
public void init() throws ServletException {
super.init();
//读取Spring配置文件,构造IOC容器
context = new ClassPathXmlApplicationContext("spring.xml");
}
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
/*请求规范
访问路径规范:
/staff/add.do——普通模块
/login.do——特殊模块
控制器命名规范:
staffController
控制器中方法命名规范:方法名称需要与"staff/add.do"中的"add"对应
public void add(HttpServletRequest request, HttpServletResponse response){}
*
*/
/*获取用户请求的URL,去掉URL中第一个"/"*/
/*访问路径就会变为这种格式:
staff/add.do——普通模块
login.do——特殊模块
* */
String path = request.getServletPath().substring(1);
String beanName = null;
String methodName = null;
//再次查找"/"的位置
int index = path.indexOf('/');
if (index != -1) {//若还存在"/",则为staff/add.do——普通模块
beanName = path.substring(0, index) + "Controller";//获取控制器名称,再次对访问路径进行截取,只保留"/"前的位置,如:staff
methodName = path.substring(index + 1, path.indexOf(".do"));//获取控制器中方法名称,再次对访问路径进行截取,只保留"/"后直到"."的位置,如:add
} else {//若不存在"/",则为login.do——特殊模块
beanName = "selfController";
methodName = path.substring(0, path.indexOf(".do"));
}
//从IOC容器中获取bean
Object obj = context.getBean(beanName);
//获取控制器方法
try {
Method method = obj.getClass().getMethod(methodName,HttpServletRequest.class,HttpServletResponse.class);
method.invoke(obj,request,response);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
- 在sm_web模块中的web.xml配置
<servlet>
<servlet-name>Global</servlet-name>
<servlet-class>com.imooc.sm.global.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Global</servlet-name>
<url-pattern>*.do</url-pattern><!--所有以".do"为后缀的请求,全部交给核心控制器完成-->
</servlet-mapping>
2.7.3、核心控制器测试
2.7.3.1、测试工具类、配置文件在语法上是否存在问题
1.在sm_web模块中的webapp下新建show.jsp
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2021/6/10
Time: 8:10
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>
你好,世界!
</body>
</html>
直接右键run show.jsp,此时idea会自动添加一个Tomcat的部署配置
若没有异常,页面会正常显示,访问路径为http://localhost:8080/show.jsp
若存在异常,检测Tomcat中的上下文路径Application context配置应为空
- 在一个项目中 ,有很多页面要显示,但显示的内容通常是活的,并不是写死在页面上,内容可能是一些数据,那么此时就牵扯到数据传递的问题。
- 而在MVC模式的要求下,JSP页面作为视图,是不允许主动获取数据抓取数据的,应该由控制器获取数据后,传递给JSP,所以接下来创建控制器来进行测试
2.7.3.2、测试显示信息控制器
- 在sm_web模块下>com.imooc.sm.controller包下>新建TestController类(test控制器)
package com.imooc.sm.controller;
import org.springframework.stereotype.Controller;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Controller("testController")//通过注解将该控制器加入IOC容器,同时指定该控制器在IOC容器中的标识,该控制器的名称为test
public class TestController {
/*该类中会存在若干个方法,每一个方法就是一个控制器方法,这些控制器方法访问路径需遵循这样一个规范
* 比如访问路径为:/test/*.do
* 其中"test"代表"@Controller("testController")"注解中的test+Controller中的test,即该控制器类的名称test
* 其中"*"就代表方法名
* */
//show方法作为一个控制器方法,它的访问路径为:/test/show.do
public void show(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//该控制器方法的功能为向页面传递数据
request.setAttribute("NAME","张三");
//传递结束后跳转show.jsp,"show.jsp"位置在sm_web模块下webapp文件夹下(根目录)即:/show.jsp
//当前控制器方法的访问路径为:/test/show.do
//说明show.jsp的位置在这个控制器show方法的上一层目录,故该控制器show方法访问show.jsp路径应为上一层的show.jsp
request.getRequestDispatcher("../show.jsp").forward(request,response);
}
}
启动Tomcat,在浏览器输入http://localhost:8080/test/show.do
核心控制器成功处理这一次请求匹配IOC容器里对应的控制器对应的方法
注意:访问路径为什么是/test/show.do
因为核心控制器本身就是我们自己编写的,在web.xml中我们配置了*.do
的请求交个核心控制器
同时又在核心控制器里面分析路径时,我们判断的是访问路径以.do
结尾
2.7.3.3、删除测试代码
- 删除show.jsp
- 删除com.imooc.sm.controller包下>TestController类
- 删除Tomcat部署
3、功能实现
3.1、部门管理
实现对部门信息的增删改查
步骤
- 实体类
- Dao接口与Sql映射文件
- Service接口与其实现类
- 控制器
- 页面
3.1.1、实现持久层
在sm_service模块下
- 在com.imooc.sm.entity包下>新建Department (实体类)
package com.imooc.sm.entity;
public class Department {
private Integer id;
private String name;
private String address;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
- 在java文件夹下>com.imooc.sm.dao包下>新建DepartmentDao (持久化操作接口)
package com.imooc.sm.dao;
import com.imooc.sm.entity.Department;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository("departmentDao")
public interface DepartmentDao {
void insert(Department department);
void delete(Integer id);
void update(Department department);
Department selectById(Integer id);
List<Department> selectAll();
}
- 创建映射文件DepartmentDao.xml
在resources下创建com/imooc/sm/dao文件夹>创建映射文件DepartmentDao.xml
保持访问路径一致
- DepartmentDao.xml映射文件放置在resources下的com/imooc/sm/dao文件夹中
- 持久化操作接口DepartmentDao放置在java文件夹下的com.imooc.sm.dao包中
- 这样才能保证所访问路径保持一致(访问路径一致,不是放置在同一个地方)
注意
在resources下创建目录
不能用com.imooc.sm.dao,因为这样创建出来的是一个一级目录,
只能使用com/imooc/sm/dao,这样创建出来的才是一个多级目录。
如果按照com.imooc.sm.dao创建目录,这样经过maven编译之后,xml文件和Dao接口不是在一个目录下!这样就无法进行映射了!
保持映射文件名称 需与 持久化操作接口名称 一致
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.4//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--
mapper 用于定义一个映射配置文件的根节点
namespace属性是用来配置命名空间,主要进行session级别的缓存管理,命名空间默认情况下,使用我们当前操作的实体类的全路径
-->
<mapper namespace="com.imooc.sm.dao.DepartmentDao">
<!--配置实体类与数据库表名映射关系-->
<resultMap id="resultMap" type="Department">
<!--property配置的是实体类的属性名称,column表示配置的是数据库字段名称-->
<!--若实体类的属性对应的数据库字段是主键,则使用id标签-->
<id property="id" column="id" javaType="Integer"/>
<!--若实体类的属性对应的数据库字段不是主键,则使用result标签-->
<result property="name" column="name" javaType="String"/>
<result property="address" column="address" javaType="String"/>
</resultMap>
<!--配置SQL-->
<!--parameterType为配置参数,useGeneratedKeys为调用数据库自增规范(可见MyBatis第十章)-->
<insert id="insert" parameterType="Department" useGeneratedKeys="true">
insert into department(name,address) values(#{name},#{address})
</insert>
<delete id="delete" parameterType="Integer">
delete from department where id=#{id}
</delete>
<update id="update" parameterType="Department">
update department set name=#{name},address=#{address} where id=#{id}
</update>
<!--resultMap表示返回的结果类型-->
<select id="selectById" parameterType="Integer" resultMap="resultMap">
select * from department where id=#{id}
</select>
<select id="selectAll" resultMap="resultMap">
select * from department
</select>
</mapper>
3.1.2、实现业务层
在sm_service模块下
- 在com.imooc.sm.service包下>新建DepartmentService (业务层接口)
package com.imooc.sm.service;
import com.imooc.sm.entity.Department;
import java.util.List;
public interface DepartmentService {
void add(Department department);
void remove(Integer id);
void edit(Department department);
Department get(Integer id);
List<Department> getAll();
}
- 新建com.imooc.sm.service.impl包>新建DepartmentServiceImpl (业务层实现类)
package com.imooc.sm.service.impl;
import com.imooc.sm.dao.DepartmentDao;
import com.imooc.sm.entity.Department;
import com.imooc.sm.service.DepartmentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service("departmentService")
public class DepartmentServiceImpl implements DepartmentService {
@Autowired
private DepartmentDao departmentDao;
public void add(Department department) {
departmentDao.insert(department);
}
public void remove(Integer id) {
departmentDao.delete(id);
}
public void edit(Department department) {
departmentDao.update(department);
}
public Department get(Integer id) {
return departmentDao.selectById(id);
}
public List<Department> getAll() {
return departmentDao.selectAll();
}
}
3.1.3、实现表现层
在sm_web模块下
- com.imooc.sm.controller包下>新建DepartmentController (控制器)
package com.imooc.sm.controller;
import com.imooc.sm.entity.Department;
import com.imooc.sm.service.DepartmentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
@Controller("departmentController")//通过注解将该控制器加入IOC容器,同时指定该控制器在IOC容器中的标识,该控制器的名称为department
public class DepartmentController {
@Autowired
private DepartmentService departmentService;
//列表显示功能
//list方法作为一个控制器方法,它的访问路径为:/department/list.do
public void list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Department> list = departmentService.getAll();
request.setAttribute("LIST",list);
//department_list.jsp页面作为视图
//"department_list.jsp"位置在sm_web模块下webapp文件夹下(根目录)即:/department_list.jsp
//说明department_list.jsp的位置在这个控制器list方法的上一层目录,故该控制器list方法访问department_list.jsp路径应为上一层的department_list.jsp
request.getRequestDispatcher("../department_list.jsp").forward(request,response);
}
//跳转添加页面功能
public void toAdd(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("../department_add.jsp").forward(request,response);
}
//部门添加功能
public void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getParameter("name");
String address = request.getParameter("address");
Department department = new Department();
department.setName(name);
department.setAddress(address);
departmentService.add(department);
response.sendRedirect("list.do");//响应重定向回控制器列表显示方法
}
//跳转修改数据页面功能
public void toEdit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Integer id = Integer.parseInt(request.getParameter("id"));
Department department = departmentService.get(id);
request.setAttribute("OBJ",department);//用于页面取该department对象原来设定的属性值
request.getRequestDispatcher("../department_edit.jsp").forward(request,response);
}
//修改数据功能
public void edit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Integer id = Integer.parseInt(request.getParameter("id"));
String name = request.getParameter("name");
String address = request.getParameter("address");
Department department = new Department();
department.setId(id);
department.setName(name);
department.setAddress(address);
departmentService.edit(department);
response.sendRedirect("list.do");
}
//删除功能
public void remove(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Integer id = Integer.parseInt(request.getParameter("id"));
departmentService.remove(id);
response.sendRedirect("list.do");
}
}
JSP页面的编码,我就不放出来了,现在基本不会在使用JSP,该项目只是为了演示Spring+Mybatis+Servlet案例,大家可以自行通过案例源码下载查看
3.2、员工管理
实现员工信息的增删改查
关注点
- 员工与部门的关联关系
- 默认登陆密码
步骤
- 实体类
- Dao接口与Sql映射文件
- Service接口与其实现类
- 控制器
- 页面
3.2.1、实现持久层
在sm_service模块下
- 在com.imooc.sm.entity包下>新建Staff (实体类)
package com.imooc.sm.entity;
import java.util.Date;
public class Staff {
private Integer id;
private String account;
private String password;
private String status;
private Integer did;
private String name;
private String sex;
private String idNumber;
private Date workTime;
private Date leaveTime;
private Date bornDate;
private String info;
private Department department;
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Integer getDid() {
return did;
}
public void setDid(Integer did) {
this.did = did;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getIdNumber() {
return idNumber;
}
public void setIdNumber(String idNumber) {
this.idNumber = idNumber;
}
public Date getWorkTime() {
return workTime;
}
public void setWorkTime(Date workTime) {
this.workTime = workTime;
}
public Date getLeaveTime() {
return leaveTime;
}
public void setLeaveTime(Date leaveTime) {
this.leaveTime = leaveTime;
}
public Date getBornDate() {
return bornDate;
}
public void setBornDate(Date bornDate) {
this.bornDate = bornDate;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
}
需要注意
在数据库中字段类型为 datetime、date,在java中对应的类型为 java.util.Date
- 在java文件夹下>com.imooc.sm.dao包下>新建StaffDao (持久化操作接口)
package com.imooc.sm.dao;
import com.imooc.sm.entity.Staff;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository("staffDao")
public interface StaffDao {
void insert(Staff staff);
void delete(Integer id);
void update(Staff staff);
Staff selectById(Integer id);
List<Staff> selectAll();
}
- 创建映射文件StaffDao.xml
在resources下com/imooc/sm/dao文件夹>创建映射文件StaffDao.xml
下面的映射文件中出现了多表联查,关于多表联查可以看看这篇文章
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.4//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.imooc.sm.dao.StaffDao">
<resultMap id="resultMap" type="Staff">
<id property="id" column="id" javaType="Integer"/>
<result property="account" column="account" javaType="String"/>
<result property="password" column="password" javaType="String"/>
<result property="status" column="status" javaType="String"/>
<result property="did" column="did" javaType="Integer"/>
<result property="name" column="name" javaType="String"/>
<result property="sex" column="sex" javaType="String"/>
<result property="idNumber" column="id_number" javaType="String"/>
<result property="workTime" column="work_time" javaType="java.util.Date"/>
<result property="leaveTime" column="leave_time" javaType="java.util.Date"/>
<result property="bornDate" column="born_date" javaType="java.util.Date"/>
<result property="info" column="info" javaType="String"/>
<!--配置多表联查-->
<association property="department" column="did" javaType="Department" select="com.imooc.sm.dao.DepartmentDao.selectById" />
</resultMap>
<insert id="insert" parameterType="Staff" useGeneratedKeys="true">
insert into staff(account,password,status,did,name,sex,id_number,work_time,leave_time,born_date,info)
values(#{account},#{password},#{status},#{did},#{name},#{sex},#{idNumber},#{workTime},#{leaveTime},#{bornDate},#{info})
</insert>
<delete id="delete" parameterType="Integer">
delete from staff where id=#{id}
</delete>
<update id="update" parameterType="Staff">
update staff set account=#{account},password=#{password},status=#{status},
did=#{did},name=#{name},sex=#{sex},id_number=#{idNumber},
work_time=#{workTime},leave_time=#{leaveTime},born_date=#{bornDate},info=#{info} where id=#{id}
</update>
<select id="selectById" parameterType="Integer" resultMap="resultMap">
select * from staff where id=#{id}
</select>
<select id="selectAll" resultMap="resultMap">
select * from staff
</select>
</mapper>
3.2.2、实现业务层
在sm_service模块下
- 在com.imooc.sm.service包下>新建StaffService (业务层接口)
package com.imooc.sm.service;
import com.imooc.sm.entity.Staff;
import java.util.List;
public interface StaffService {
void add(Staff staff);
void remove(Integer id);
void edit(Staff staff);
Staff get(Integer id);
List<Staff> getAll();
}
- com.imooc.sm.service.impl包>新建StaffServiceImpl (业务层实现类)
package com.imooc.sm.service.impl;
import com.imooc.sm.dao.StaffDao;
import com.imooc.sm.entity.Staff;
import com.imooc.sm.service.StaffService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
@Service("staffService")
public class StaffServiceImpl implements StaffService {
@Autowired
private StaffDao staffDao;
public void add(Staff staff) {
staff.setPassword("123456");//设置默认密码
staff.setWorkTime(new Date());//设置默认入职日期
staff.setStatus("正常");//设置默认状态
staffDao.insert(staff);
}
public void remove(Integer id) {
staffDao.delete(id);
}
public void edit(Staff staff) {
staffDao.update(staff);
}
public Staff get(Integer id) {
return staffDao.selectById(id);
}
public List<Staff> getAll() {
return staffDao.selectAll();
}
}
3.2.3、实现表现层
在sm_web模块下
- com.imooc.sm.controller包下>新建StaffController(控制器)
package com.imooc.sm.controller;
import com.imooc.sm.entity.Department;
import com.imooc.sm.entity.Staff;
import com.imooc.sm.service.DepartmentService;
import com.imooc.sm.service.StaffService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
@Controller("staffController")
public class StaffController {
@Autowired
private StaffService staffService;
@Autowired
private DepartmentService departmentService;
public void list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Staff> list = staffService.getAll();
request.setAttribute("LIST",list);
request.getRequestDispatcher("../staff_list.jsp").forward(request,response);
}
public void toAdd(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Department> list = departmentService.getAll();
request.setAttribute("DLIST",list);
request.getRequestDispatcher("../staff_add.jsp").forward(request,response);
}
public void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String account = request.getParameter("account");
String name = request.getParameter("name");
String sex = request.getParameter("sex");
String idNumber = request.getParameter("idNumber");
String info =request.getParameter("info");
Date bornDate=null;
try {//request中接收值为String类型,这里进行String转为java.util.Date
bornDate = new SimpleDateFormat("yyyy-MM-dd").parse(request.getParameter("bornDate"));
} catch (ParseException e) {
e.printStackTrace();
}
Integer did = Integer.parseInt(request.getParameter("did"));
Staff staff = new Staff();
staff.setInfo(info);
staff.setBornDate(bornDate);
staff.setIdNumber(idNumber);
staff.setDid(did);
staff.setAccount(account);
staff.setName(name);
staff.setSex(sex);
staffService.add(staff);
response.sendRedirect("list.do");
}
public void toEdit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Integer id = Integer.parseInt(request.getParameter("id"));
Staff staff = staffService.get(id);
request.setAttribute("OBJ",staff);
List<Department> list = departmentService.getAll();
request.setAttribute("DLIST",list);
request.getRequestDispatcher("../staff_edit.jsp").forward(request,response);
}
public void edit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Integer id = Integer.parseInt(request.getParameter("id"));
String account = request.getParameter("account");
String name = request.getParameter("name");
String sex = request.getParameter("sex");
String idNumber = request.getParameter("idNumber");
String info =request.getParameter("info");
Date bornDate=null;
try {
bornDate = new SimpleDateFormat("yyyy-MM-dd").parse(request.getParameter("bornDate"));
} catch (ParseException e) {
e.printStackTrace();
}
Integer did = Integer.parseInt(request.getParameter("did"));
Staff staff = staffService.get(id);
staff.setInfo(info);
staff.setBornDate(bornDate);
staff.setIdNumber(idNumber);
staff.setDid(did);
staff.setAccount(account);
staff.setName(name);
staff.setSex(sex);
// 在完成3.3.3节后打开注释
// /**由于staff是之前数据库中查询出来的,department属性没有修改,只修改了did属性
// * 所以,我们把department根据did属性查询出来并设置给staff的department属性*/
// Department department = departmentService . get(did);
// staff.setDepartment (department);
// //判断一下, 如果当前修改的用户与当前登录的用户是同一个,把修改后的用户放到session 中
// Staff staff1 = (Staff) request. getSession(). getAttribute("USER");
// if(staff1. getId().equals(staff.getId())){
// request.getSession(). setAttribute("USER" ,staff);
// }
staffService.edit(staff);
response.sendRedirect("list.do");
}
public void remove(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Integer id = Integer.parseInt(request.getParameter("id"));
staffService.remove(id);
response.sendRedirect("list.do");
}
public void detail(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Integer id = Integer.parseInt(request.getParameter("id"));
Staff staff = staffService.get(id);
request.setAttribute("OBJ",staff);
request.getRequestDispatcher("../staff_detail.jsp").forward(request,response);
}
}
JSP页面的编码,我就不放出来了,现在基本不会在使用JSP,该项目只是为了演示Spring+Mybatis+Servlet案例,大家可以自行通过案例源码下载查看
3.3、登录与个人中心
实现登陆、退出、个人信息、修改密码
关注点
- Session操作
- 登陆过滤器
步骤
- 实体类(就是3.2中定义的staff实体类)
- Dao接口与Sql映射文件
- Service接口与其实现类
- 控制器
- 页面
3.3.1、实现持久层
在sm_service模块下
因实体类就是3.2中定义的staff实体类,故直接定义dao
- 在java文件夹下>com.imooc.sm.dao包下>新建StaffDao (持久化操作接口)
package com.imooc.sm.dao;
import com.imooc.sm.entity.Staff;
import org.springframework.stereotype.Repository;
@Repository("selfDao")
public interface SelfDao {
Staff selectByAccount(String account);
}
- 创建映射文件SelfDao.xml
在resources下com/imooc/sm/dao文件夹>创建映射文件SelfDao.xml
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.4//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.imooc.sm.dao.SelfDao">
<select id="selectByAccount" parameterType="String" resultMap="com.imooc.sm.dao.StaffDao.resultMap">
select * from staff where account=#{account}
</select>
</mapper>
3.3.2、实现业务层
在sm_service模块下
- 在com.imooc.sm.service包下>新建SelfService (业务层接口)
package com.imooc.sm.service;
import com.imooc.sm.entity.Staff;
public interface SelfService {
Staff login(String account, String password);
void changePassword(Integer id,String password);
}
- com.imooc.sm.service.impl包>新建SelfServiceImpl (业务层实现类)
package com.imooc.sm.service.impl;
import com.imooc.sm.dao.SelfDao;
import com.imooc.sm.dao.StaffDao;
import com.imooc.sm.entity.Staff;
import com.imooc.sm.service.SelfService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service("selfService")
public class SelfServiceImpl implements SelfService {
@Autowired
private SelfDao selfDao;
@Autowired
private StaffDao staffDao;
public Staff login(String account, String password) {
Staff staff =selfDao.selectByAccount(account);
if(staff==null)return null;
if(staff.getPassword().equals(password))return staff;
return null;
}
public void changePassword(Integer id, String password) {
Staff staff = staffDao.selectById(id);
staff.setPassword(password);
staffDao.update(staff);
}
}
3.3.3、实现表现层
在sm_web模块下
- com.imooc.sm.global包下>新建LoginFilter (登陆过滤器)
package com.imooc.sm.global;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class LoginFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request=(HttpServletRequest)servletRequest;
HttpServletResponse response = (HttpServletResponse)servletResponse;
//获取访问路径
String path = request.getServletPath();
if(path.toLowerCase().indexOf("login")!=-1){
filterChain.doFilter(request,response);
}else{
HttpSession session = request.getSession();
Object obj =session.getAttribute("USER");
if(obj!=null){
filterChain.doFilter(request,response);
}else{//getContextPath获取请求上下文
response.sendRedirect(request.getContextPath()+"/toLogin.do");
}
}
}
public void destroy() {
}
}
- com.imooc.sm.controller包下>新建SelfController (控制器)
package com.imooc.sm.controller;
import com.imooc.sm.entity.Staff;
import com.imooc.sm.service.SelfService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@Controller("selfController")
public class SelfController {
@Autowired
private SelfService selfService;
//实现打开登录界面功能,访问路径:/toLogin.do
public void toLogin(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("login.jsp").forward(request,response);
}
//实现登录功能,路径:/login.do
public void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String account =request.getParameter("account");
String password = request.getParameter("password");
Staff staff = selfService.login(account,password);
if(staff==null){
response.sendRedirect("toLogin.do");
}else{
HttpSession session = request.getSession();
session.setAttribute("USER",staff);
response.sendRedirect("main.do");
}
}
//实现退出功能,路径:/logout.do
public void logout(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
session.setAttribute("USER", null);
response.sendRedirect("toLogin.do");
}
//实现打开主界面功能,访问路径:/main.do
public void main(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("index.jsp").forward(request,response);
}
//实现打开个人信息界面功能,访问路径:/self/info.do
public void info(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("../info.jsp").forward(request,response);
}
//实现打开修改密码界面功能,访问路径:/self/toChangePassword.do
public void toChangePassword(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("../change_password.jsp").forward(request,response);
}
//实现修改密码功能,访问路径:/self/changePassword.do
public void changePassword(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String password = request.getParameter("password");
String password1 = request.getParameter("password1");
HttpSession session = request.getSession();
Staff staff = (Staff)session.getAttribute("USER");
if(!staff.getPassword().equals(password)){
response.sendRedirect("toChangePassword.do");
}else{
selfService.changePassword(staff.getId(),password1);
//response.sendRedirect("../logout.do");
//使用javascript使父窗口跳转../logout.do
response.getWriter().print("<script type=\"text/javascript\">parent.location.href=\"../logout.do\"</script>");
}
}
}
JSP页面的编码,我就不放出来了,现在基本不会在使用JSP,该项目只是为了演示Spring+Mybatis+Servlet案例,大家可以自行通过案例源码下载查看
3.4、日志处理
实现日志查看、自动记录
关注点
- 业务功能设计
- 通知处理
步骤
- 实体类(就是3.2中定义的staff实体类)
- Dao接口与Sql映射文件
- Service接口与其实现类
- 控制器
- 页面
3.4.1、实现持久层
在sm_service模块下
- 在com.imooc.sm.entity包下>新建Log (实体类)
package com.imooc.sm.entity;
import java.util.Date;
public class Log {
private Date oprTime;
private String type;
private String operator;
private String moudle;
private String operation;
private String result;
public Date getOprTime() {
return oprTime;
}
public void setOprTime(Date oprTime) {
this.oprTime = oprTime;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getOperator() {
return operator;
}
public void setOperator(String operator) {
this.operator = operator;
}
public String getMoudle() {
return moudle;
}
public void setMoudle(String moudle) {
this.moudle = moudle;
}
public String getOperation() {
return operation;
}
public void setOperation(String operation) {
this.operation = operation;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
}
- 在java文件夹下>com.imooc.sm.dao包下>新建LogDao (持久化操作接口)
package com.imooc.sm.dao;
import com.imooc.sm.entity.Log;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository("logDao")
public interface LogDao {
void insert(Log log);
List<Log> selectByType(String type);
}
- 创建映射文件LogDao.xml
在resources下com/imooc/sm/dao文件夹>创建映射文件LogDao.xml
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.4//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.imooc.sm.dao.LogDao">
<resultMap id="resultMap" type="Log">
<result property="oprTime" column="opr_time" javaType="java.util.Date"/>
<result property="type" column="type" javaType="String"/>
<result property="operator" column="operator" javaType="String"/>
<result property="moudle" column="moudle" javaType="String"/>
<result property="operation" column="operation" javaType="String"/>
<result property="result" column="result" javaType="String"/>
</resultMap>
<insert id="insert" parameterType="Log">
insert into log values(#{oprTime},#{type},#{operator},#{moudle},#{operation},#{result});
</insert>
<select id="selectByType" parameterType="String" resultMap="resultMap">
select * from log where type=#{type} order by opr_time desc
</select>
</mapper>
3.4.2、实现业务层
在sm_service模块下
- 在com.imooc.sm.service包下>新建LogService (业务层接口)
package com.imooc.sm.service;
import com.imooc.sm.entity.Log;
import java.util.List;
public interface LogService {
void addSystemLog(Log log);
void addLoginLog(Log log);
void addOperationLog(Log log);
List<Log> getSystemLog();
List<Log> getLoginLog();
List<Log> getOperationLog();
}
- com.imooc.sm.service.impl包>新建SelfServiceImpl (业务层实现类)
package com.imooc.sm.service.impl;
import com.imooc.sm.dao.LogDao;
import com.imooc.sm.entity.Log;
import com.imooc.sm.service.LogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
@Service("logService")
public class LogServiceImpl implements LogService {
@Autowired
private LogDao logDao;
public void addSystemLog(Log log) {
log.setOprTime(new Date());
log.setType("system");
logDao.insert(log);
}
public void addLoginLog(Log log) {
log.setOprTime(new Date());
log.setType("login");
logDao.insert(log);
}
public void addOperationLog(Log log) {
log.setOprTime(new Date());
log.setType("operation");
logDao.insert(log);
}
public List<Log> getSystemLog() {
return logDao.selectByType("system");
}
public List<Log> getLoginLog() {
return logDao.selectByType("login");
}
public List<Log> getOperationLog() {
return logDao.selectByType("operation");
}
}
什么时候记录日志?
- 日志里面需要记录操作员,操作员在web层session中保存,所以处理用户请求的时候,记录日志这是最合理的,也就是在某个控制器方法被调用时,我们去调用记录日志的功能
- 但是记录日志的代码不能写在被调用的控制器方法中,第一是要记录日志的方法太多,工作量太大,第二被调永的控制器方法是为了处理用户的某种请求,与记录日志没有本质关系
- 所以记录日志应该使用切面处理,然后自动注入
在sm_web模块下
3. com.imooc.sm.global包下>新建LogAdvice (切面类)
package com.imooc.sm.global;
import com.imooc.sm.entity.Log;
import com.imooc.sm.entity.Staff;
import com.imooc.sm.service.LogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@Component
@Aspect
public class LogAdvice {
@Autowired
private LogService logService;
// && !表示去除
@AfterReturning("execution(* com.imooc.sm.controller.*.*(..)) && !execution(* com.imooc.sm.controller.SelfController.*(..)) && !execution(* com.imooc.sm.controller.*.to*(..))")
public void operationLog(JoinPoint joinPoint){
Log log = new Log();
//JoinPoint连接点对象,用来获得切点所在类与切点方法名,直接输出为切点方法名称(全路径)
//获取切点所在类的类名(获取当前操作的模块)
log.setMoudle(joinPoint.getTarget().getClass().getSimpleName());
//获取切点方法名称(获取当前进行的操作名称)
log.setOperation(joinPoint.getSignature().getName());
//获取当前当前操作人
//joinPoint.getArgs()[0]获取获取当前切点操作的request
HttpServletRequest request =(HttpServletRequest) joinPoint.getArgs()[0];
HttpSession session = request.getSession();
Object obj = session.getAttribute("USER");
Staff staff =(Staff)obj;
log.setOperator(staff.getAccount());
log.setResult("成功");
logService.addOperationLog(log);
}
@AfterThrowing(throwing ="e",pointcut ="execution(* com.imooc.sm.controller.*.*(..)) && !execution(* com.imooc.sm.controller.SelfController.*(..))")
public void systemLog(JoinPoint joinPoint,Throwable e){
Log log = new Log();
log.setMoudle(joinPoint.getTarget().getClass().getSimpleName());
log.setOperation(joinPoint.getSignature().getName());
HttpServletRequest request =(HttpServletRequest) joinPoint.getArgs()[0];
HttpSession session = request.getSession();
Object obj = session.getAttribute("USER");
Staff staff =(Staff)obj;
log.setOperator(staff.getAccount());
log.setResult(e.getClass().getSimpleName());
logService.addSystemLog(log);
}
@After("execution(* com.imooc.sm.controller.SelfController.login(..))")
public void loginLog(JoinPoint joinPoint){
log(joinPoint);
}
@Before("execution(* com.imooc.sm.controller.SelfController.logout(..))")
public void logoutLog(JoinPoint joinPoint){
log(joinPoint);
}
private void log(JoinPoint joinPoint){
Log log = new Log();
log.setMoudle(joinPoint.getTarget().getClass().getSimpleName());
log.setOperation(joinPoint.getSignature().getName());
HttpServletRequest request =(HttpServletRequest) joinPoint.getArgs()[0];
HttpSession session = request.getSession();
Object obj = session.getAttribute("USER");
if(obj==null){
log.setOperator(request.getParameter("account"));
log.setResult("失败");
}else {
Staff staff = (Staff) obj;
log.setOperator(staff.getAccount());
log.setResult("成功");
}
logService.addLoginLog(log);
}
}
3.4.3、实现表现层
在sm_web模块下
- com.imooc.sm.controller包下>新建LogController (控制器)
package com.imooc.sm.controller;
import com.imooc.sm.entity.Department;
import com.imooc.sm.entity.Log;
import com.imooc.sm.service.LogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
@Controller("logController")
public class LogController {
@Autowired
private LogService logService;
public void operationLog(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Log> list = logService.getOperationLog();
request.setAttribute("LIST",list);
request.setAttribute("TYPE","操作");
request.getRequestDispatcher("../log_list.jsp").forward(request,response);
}
public void loginLog(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Log> list = logService.getLoginLog();
request.setAttribute("LIST",list);
request.setAttribute("TYPE","登陆");
request.getRequestDispatcher("../log_list.jsp").forward(request,response);
}
public void systemLog(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Log> list = logService.getSystemLog();
request.setAttribute("LIST",list);
request.setAttribute("TYPE","系统");
request.getRequestDispatcher("../log_list.jsp").forward(request,response);
}
}
JSP页面的编码,我就不放出来了,现在基本不会在使用JSP,该项目只是为了演示Spring+Mybatis+Servlet案例,大家可以自行通过案例源码下载查看
到这里该项目就结束了