基于SSM框架实现后台数据管理系统

目录

一. 前言

二. 主要技术栈

三.项目搭建

3.1 数据库搭建

3.2 maven项目搭建

四、实现基本的CRUD操作

五、SpringAOP实现记录日志

六、SpringMVC拦截器interceptor拦截用户的权限

七、Bcrypt加密算法

八、总结


一. 前言

本项目的客户端是基于开源项目AdminLTE 和AdminLTE 黑马定制版进行编写。AdminLTE 是一个完全的响应式管理模板,基于Bootstrap3框架,高度可定制,易于使用。适合从小型移动设备到大型台式机的屏幕分辨率 。

本项目可实现用户登录与头像的上传,根据用户的角色与权限不同,操作不同的模块进行基本的CRUD操作。实现对用户的请求进行日志记录,对用户的权限进行监控与拦截,用户在没有登录的情况下,不能对后台进行访问操作,当点击菜单就会跳转到登录页面。只有用户登录成功,才能进行后台功能的操作。对用户的密码进行加密与解密,整合redis实现mybatis的二级缓存。

 


二. 主要技术栈

  • 前端页面:Bootstrap3框架,Jquery,JSP
  • 后端:JavaEE,SSM框架,redis,spring-security,bcrypt加密算法

开发工具:jdk8,idea2022,navicat,redis,mysql8,maven仓库,firefox/chorm


三.项目搭建

3.1 数据库搭建

打开navicat,创建名为ssm的数据库,导入准备好的sql脚本文件,数据库模型图如下所示,共11张表。用户表通过中间表与角色表相连,角色表通过中间表与权限表相连;订单表通过外键与订单负责人相连、通过中间表与旅客表进行相连。syslog为日志记录表,product为产品表。

3.2 maven项目搭建

打开idea新建maven工程,在pom文件中添加对应的依赖,具体的依赖如下所示。



    4.0.0

    com.jbz
    ssm
    1.0-SNAPSHOT
    ssm
    war

    
        UTF-8
        1.8
        1.8
        
        5.0.5.RELEASE
    

    
        
        
            junit
            junit
            4.13.2
            test
        
        
        
            javax.servlet
            javax.servlet-api
            3.1.0
            provided
        
        
        
            javax.servlet.jsp
            javax.servlet.jsp-api
            2.2.1
            provided
        
        
        
            javax.servlet
            jstl
            1.1.2
        
        
            taglibs
            standard
            1.1.2
        
        
        
            mysql
            mysql-connector-java
            8.0.28
            compile
        
        
        
            com.alibaba
            druid
            1.2.15
        
        
        
            org.springframework
            spring-context
            5.0.5.RELEASE
        
        
            org.springframework
            spring-core
            5.0.5.RELEASE
        
        
            org.springframework
            spring-tx
            5.0.5.RELEASE
            compile
        
        
            org.springframework
            spring-beans
            5.0.5.RELEASE
            compile
        
        
            org.springframework
            spring-jdbc
            5.0.5.RELEASE
            compile
        
        
            org.springframework
            spring-test
            5.0.5.RELEASE
        
        
        
            org.aspectj
            aspectjweaver
            1.9.4
        
        
        
            org.springframework
            spring-webmvc
            5.0.5.RELEASE
        
        
        
            org.mybatis
            mybatis
            3.5.6
        
        
        
            com.baomidou
            mybatis-plus
            3.4.3.4
        
        
        
            org.mybatis
            mybatis-spring
            1.3.2
        
        
        
            com.google.code.gson
            gson
            2.4
        
        
        
            com.fasterxml.jackson.core
            jackson-core
            2.9.0
        
        
            com.fasterxml.jackson.core
            jackson-databind
            2.9.0
        
        
            com.fasterxml.jackson.core
            jackson-annotations
            2.9.0
        
        
        
            com.github.pagehelper
            pagehelper
            5.1.2
        
        
        
            commons-fileupload
            commons-fileupload
            1.2.2
        
        
            commons-io
            commons-io
            2.4
        
        
        
            org.springframework.data
            spring-data-redis
            1.4.0.RELEASE
        
        
            redis.clients
            jedis
            2.4.2
        
        
        
            org.springframework.security
            spring-security-core
            5.0.5.RELEASE
        
    

    
        
            
                org.apache.tomcat.maven
                
                tomcat7-maven-plugin
                2.1
                
                    
                    80
                    
                    /
                    UTF-8
                
            
        

        
            
                src/main/java
                
                
                    **/*.xml
                
                false
            
            
            
                src/main/resources
                
                    **/*.xml
                    *.xml
                    *.properties
                
            
        
    

添加完记得刷新一下,接下来在resource文件下添加jdbc.properties文件

基于SSM框架实现后台数据管理系统_第1张图片

添加SqlMapperConfig文件





    
        
        
        
        
        
        
        
        
        
        
    
    
    
        
            
        
    
    
        
    

添加spring-mvc.xml



    
    
    
    
    
    
        
        
        
        
    
    
    
    
    
        
            
            
            
            
            
        
    
    
    
        
        
        
        
        
        
    

添加applicationContext.xml



    
    
    
    
        
        
        
        
    
    
    
        
        
        
        
        
        
    
    
    
        
        
    
    
    
    
    

添加redis.properties

基于SSM框架实现后台数据管理系统_第2张图片

添加application-redis.xml



    
    
    
    
    
        
        
        
        
        
        
    
    
    
        
        
        
        
        
    
    
        
        
        
            
        
        
            
        
        
            
        
        
    
    
    
    
        
    
    
    
        
    

redis整合所需要的工具类

package com.jbz.utils;

import org.apache.ibatis.cache.Cache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import redis.clients.jedis.exceptions.JedisConnectionException;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @author: jbz
 * @date: 2023/1/10
 * @description:
 * @version: 1.0
 */
public class RedisCache implements Cache {
    private static final Logger logger = LoggerFactory.getLogger(RedisCache.class);
    private static JedisConnectionFactory jedisConnectionFactory;
    private final String id;
    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    public RedisCache(final String id) {
        if (id == null) {
            throw new IllegalArgumentException("require an ID");
        }
        logger.debug("RedisCache:id=" + id);
        this.id = id;
    }

    @Override
    public void clear() {
        RedisConnection connection = null;
        try {
            connection = jedisConnectionFactory.getConnection();
            connection.flushDb();
            connection.flushAll();
        } catch (JedisConnectionException e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.close();
            }
        }
    }
    public String getId() {
        return this.id;
    }
    public Object getObject(Object key) {
        Object result = null;
        RedisConnection connection = null;
        try {
            connection = jedisConnectionFactory.getConnection();
            RedisSerializer serializer = new JdkSerializationRedisSerializer();
            result = serializer.deserialize(connection.get(serializer.serialize(key)));
        } catch (JedisConnectionException e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.close();
            }
        }
        return result;
    }
    public ReadWriteLock getReadWriteLock() {
        return this.readWriteLock;
    }
    public int getSize() {
        int result = 0;
        RedisConnection connection = null;
        try {
            connection = jedisConnectionFactory.getConnection();
            result = Integer.parseInt(connection.dbSize().toString());
        } catch (JedisConnectionException e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.close();
            }
        }
        return result;
    }
    public void putObject(Object key, Object value) {
        RedisConnection connection = null;
        try {
            connection = jedisConnectionFactory.getConnection();
            RedisSerializer serializer = new JdkSerializationRedisSerializer();
            connection.set(serializer.serialize(key), serializer.serialize(value));
        } catch (JedisConnectionException e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.close();
            }
        }
    }
    public Object removeObject(Object key) {
        RedisConnection connection = null;
        Object result = null;
        try {
            connection = jedisConnectionFactory.getConnection();
            RedisSerializer serializer = new JdkSerializationRedisSerializer();
            result = connection.expire(serializer.serialize(key), 0);
        } catch (JedisConnectionException e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.close();
            }
        }
        return result;
    }
    public static void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) {
        RedisCache.jedisConnectionFactory = jedisConnectionFactory;
    }
}

package com.jbz.utils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;

/**
 * @author: jbz
 * @date: 2023/1/10
 * @description:
 * @version: 1.0
 */
public class RedisCacheTransfer {

    @Autowired
    public void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) {
        RedisCache.setJedisConnectionFactory(jedisConnectionFactory);
    }
}

 

 在web.xml文件中配置过滤器、前端控制器、监听器



    
    
        /pages/login.jsp
    
    
    
        CharacterEncodingFilter
        org.springframework.web.filter.CharacterEncodingFilter
        
            encoding
            UTF-8
        
    
    
        CharacterEncodingFilter
        /*
    
    
    
        DispatcherServlet
        org.springframework.web.servlet.DispatcherServlet
        
            contextConfigLocation
            classpath:*.xml
        
        
        1
    
    
        DispatcherServlet
        /
    
    
    
        default
        *.js
        *.css
        /img/*
        /plugins/*
    
    
    
        
            org.springframework.web.context.request.RequestContextListener
        
    


接下来将准备好的静态资源放在webapp下,至此项目搭建完毕 。

四、实现基本的CRUD操作

首先在main文件下新建如图所示的包:

基于SSM框架实现后台数据管理系统_第3张图片

首先在domain包下新建Product实体类,实体类的字段要与数据库product表中的字段名、类型要一致。注意:由于我们要用到redis,因此实体类必须要实现序列化接口。

package com.jbz.domain;

import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;

import java.io.Serializable;
import java.util.Date;

/**
 * @author: jbz
 * @date: 2022/12/22
 * @description:
 * @version: 1.0
 */
public class Product implements Serializable {
    //编号
    private Integer id;
    //产品编号
    private String productNum;
    //产品名称
    private String productName;
    //出发城市名称
    private String cityName;
    //出发时间
    @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date departureTime;
    private String departureTimeStr;
    //产品价格
    private Double productPrice;
    //产品详情描述
    private String productDesc;
    //产品状态 0:下架 1:上架
    private Integer productStatus;
    private String productStatusStr;

    public Product() {
    }
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getProductNum() {
        return productNum;
    }

    public void setProductNum(String productNum) {
        this.productNum = productNum;
    }

    public String getProductName() {
        return productName;
    }

    public void setProductName(String productName) {
        this.productName = productName;
    }

    public String getCityName() {
        return cityName;
    }

    public void setCityName(String cityName) {
        this.cityName = cityName;
    }

    public Date getDepartureTime() {
        return departureTime;
    }

    public void setDepartureTime(Date departureTime) {
        this.departureTime = departureTime;
    }

    public String getDepartureTimeStr() {
        return departureTimeStr;
    }

    public void setDepartureTimeStr(String departureTimeStr) {
        this.departureTimeStr = departureTimeStr;
    }

    public Double getProductPrice() {
        return productPrice;
    }

    public void setProductPrice(Double productPrice) {
        this.productPrice = productPrice;
    }

    public String getProductDesc() {
        return productDesc;
    }

    public void setProductDesc(String productDesc) {
        this.productDesc = productDesc;
    }

    public Integer getProductStatus() {
        return productStatus;
    }

    public void setProductStatus(Integer productStatus) {
        this.productStatus = productStatus;
    }

    public String getProductStatusStr() {
        if (productStatus == 0) {
            productStatusStr = "下架";
        }else if(productStatus == 1){
            productStatusStr = "上架";
        }
        return productStatusStr;
    }

    public void setProductStatusStr(String productStatusStr) {
        this.productStatusStr = productStatusStr;
    }

    @Override
    public String toString() {
        return "Product{" +
                "id='" + id + '\'' +
                ", productNum='" + productNum + '\'' +
                ", productName='" + productName + '\'' +
                ", cityName='" + cityName + '\'' +
                ", departureTime=" + departureTime +
                ", departureTimeStr='" + departureTimeStr + '\'' +
                ", productPrice=" + productPrice +
                ", productDesc='" + productDesc + '\'' +
                ", productStatus=" + productStatus +
                ", productStatusStr='" + productStatusStr + '\'' +
                '}';
    }
}

 其次我们在数据持久层mapper包下新建ProductMapper接口,添加@Repoistory注解,用来操作数据库,封装一个方法用来条件查询所有的产品,在resources文件夹下新建mapper文件夹,新建ProductMapper.xml,文件名要与接口名一致。在namespace里通过全限定类名进行映射。select标签的id要与方法名一致,返回类型与方法名返回类型一致

基于SSM框架实现后台数据管理系统_第4张图片

 基于SSM框架实现后台数据管理系统_第5张图片

 接着我们在service层新建对应的接口与实现类,在实现类中添加@Service注解,通过依赖注入,将mapper层注入到ioc容器,通过mybatis分页插件进行分页,调用方法返回PageInfo对象。

基于SSM框架实现后台数据管理系统_第6张图片

 在controller层新建ProductController,添加@Controller注解,和请求的一级路径@RequestMapping("/product"),将对应的service接口依赖注入进来,创建方法并添加二级路径@RequestMapping("/queryProductList"),具体代码如下:

    @RequestMapping("/queryProductList")
    public String queryProductList(@RequestParam(defaultValue = "1") int pageNum, @RequestParam(defaultValue = "4") int pageSize,
                                   @RequestParam(value = "productName", required = false) String productName, Model model) {
        //调用service的查询产品列表的方法
        PageInfo pageInfo = productService.queryAllProduct(pageNum, pageSize, productName);
        //设置数据 保存容器中
        model.addAttribute("pageInfo", pageInfo);
        //返回给视图
        return "product-list";
    }

方法的参数为前端页面进行分页和查询所需要的请求参数 ,将查询出的PageInfo对象添加到Model中,并返回给视图(这里的视图的前缀和后缀已经在配置文件中进行配置过了,实际的路径应该为/pages/product-list.jsp)。

接下来我们在静态页面product-list.jsp页面中,通过jstl表达式用foreach标签进行遍历出来,在对应的侧边栏产品管理上添加跳转url路径:

 

  
                                    
                                        
                                        ${product.id}
                                        ${product.productNum}
                                        ${product.productName}
                                        ${product.cityName}
                                        
                                        ${product.productPrice}
                                        ${product.productDesc}
                                        ${product.productStatusStr}
                                        
                                            
                                            
                                        
                                    
                                

最后运行项目,在点击控制台的链接,点击侧边栏的产品管理至如下图所示:

基于SSM框架实现后台数据管理系统_第7张图片

 增删改的操作与上面类似,这里就不展开说了。

五、SpringAOP实现记录日志

我们在AOP包下,新建LogAspect切面类,添加注解@Aspect声明当前类是一个切面类,添加@Pointcut注解配置通用切入点表达式。我们选择用环绕通知来进行日志的记录。环绕通知的特点是目标执行前后,都进行增强(控制目标方法执行),它的应用场景:日志、缓存、权限、性能监控、事务管理。具体代码如下所示。接着我们需要在applciationContext.xml文件中添加开启动态代理,当用户在页面发起请求时,该切面类会获取到当前用户的请求路径,请求的方法名。同时我们在此基础上获取当前用户的用户名,访问时间以及当前用户的ip地址,将这些数据封装到Syslog实体类中。最后在将Syslog实体类保存到数据库中。

基于SSM框架实现后台数据管理系统_第8张图片

 

package com.jbz.aop;

import com.jbz.constant.MessageConstant;
import com.jbz.domain.User;
import com.jbz.utils.RecordingLogUtils;
import com.jbz.utils.SetDataUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;

/**
 * @author: jbz
 * @date: 2023/1/7
 * @description: 记录日志的切面类(对用户的请求进行日志监控与记录)
 * @version: 1.0
 */
@Component
@Aspect
public class LogAspect {
    //依赖注入
    @Autowired
    private RecordingLogUtils recordingLogUtils;
    @Autowired
    private SetDataUtils setDataUtils;

    //定义方法执行开始时间
    private long startTime;
    //定义请求路径url
    private StringBuilder url;
    //获取请求方法名
    private String methodStr;
    //定义ServletRequestAttributes对象
    private static ServletRequestAttributes requestAttributes;


    //通用切入点表达式
    @Pointcut("execution (* com.jbz.controller.*.*(..))")
    private void pt1() {

    }

    //环绕通知
    @Around("pt1()")
    public Object aroundLog(ProceedingJoinPoint proceedingJoinPoint) {
        requestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
        //调用初始化方法
        init(proceedingJoinPoint);
        //设置返回值
        Object obj = null;
        //获取方法执行所需的参数
        Object[] objs = proceedingJoinPoint.getArgs();
        //获取当前用户的username
        String userName = getUserName(objs[0].toString());
        try {
            //执行切入点的方法
            obj = proceedingJoinPoint.proceed(objs);
        } catch (Throwable e) {
            setDataUtils.setExceptionCount(requestAttributes.getRequest().getSession());
            recordingLogUtils.insertSysLog(userName, MessageConstant.EXECUTE_METHOD_EXCEPTION, url.toString(), 0, methodStr);
            e.printStackTrace();
        } finally {
            //定义方法执行结束时间
            long endTime = System.currentTimeMillis();
            recordingLogUtils.insertSysLog(userName, MessageConstant.EXECUTE_METHOD_SUCCESS, url.toString(), (int) (endTime - startTime), methodStr);
        }
        return obj;
    }

    /**
     * @author: jbz
     * @description: 获得当前用户名
     * @date: 2023/1/7 19:00
     * @param: username
     * @return: String
     */
    public String getUserName(String username) {
        //获取Session对象
        HttpSession session = requestAttributes.getRequest().getSession();
        //获取当前用户
        User user = (User) session.getAttribute("user");
        //判断当前用户是否为null,为null说明未登录
        if (user == null) {
            //在未登录情况下,用户进行操作会调用拦截器进行登录,此时将参数username返回
            return username;
        } else {
            //不为null,说明当前用户处于登录状态,就将用户的username返回
            return user.getUsername();
        }
    }

    /**
     * @author: jbz
     * @description: 初始化参数
     * @date: 2023/1/7 19:39
     * @param: proceedingJoinPoint
     * @return: void
     */
    public void init(ProceedingJoinPoint proceedingJoinPoint) {
        //获取HttpSession对象
        HttpSession session = requestAttributes.getRequest().getSession();
        setDataUtils.setVisitCount(session);
        //给方法开始时间进行赋值
        startTime = System.currentTimeMillis();
        url = new StringBuilder();
        //获取执行方法的类
        Object target = proceedingJoinPoint.getTarget();
        RequestMapping[] classRequest = target.getClass().getAnnotationsByType(RequestMapping.class);
        //获取请求方法的一级路径
        url.append(classRequest[0].value()[0]);
        MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
        //获取请求方法
        Method method = signature.getMethod();
        //获取请求方法名
        methodStr = "[类名]" + target.getClass().getName() + "[方法名]" + method.getName();
        //获取请求方法的二级路径
        RequestMapping[] methodRequest = method.getAnnotationsByType(RequestMapping.class);
        url.append(methodRequest[0].value()[0]);
        if(url.toString().equals("orders/add")){
            setDataUtils.setOrderCount(session);
        }
    }


}

六、SpringMVC拦截器interceptor拦截用户的权限

SpringMVC的拦截器类似于Servlet开发中的过滤器Filter,用于处理器进行预处理和后处理。将拦截器按一定的顺序联结成一条链,这条链称为拦截器链。在访问被拦截的方法或字段时,拦截器链的拦截器就会按其之前定义的顺序被调用。拦截器也是AOP思想的具体实现。拦截器和过滤器的区别如图所示:

拦截器的步骤:

  1. 创建拦截器类实现HandlerInterceptor接口
  2. 配置拦截器
  3. 测试拦截器效果

首先我们先封装一个权限处理的工具类PermissionHandleUtils.java,该工具类用于判断请求的路径是否包含在用户所具有的权限中,并返回boolean值,随后我们创建PermissionInterceptor.java实现HanlerInterceptor接口,重写preHandle(),preHandle方法是在目标方法之前执行,是预处理。随后我们在spring-mvc文件中对拦截器进行配置,配置如下图所示。在拦截器中我们首先对用户的登录进行权限控制,用户在没有登录的情况下,不能对后台菜单进行访问操作,当用户点击菜单时,跳转至登录页面,只有在用户登录成功安置后才能进行后台功能的操作。当用户在登录状态时,通过权限处理的工具类对当前请求进行权限判断,只有满足要求,才能放行,否则就跳转至错误页面。在权限拦截的同时,还要添加日志到数据库中。

基于SSM框架实现后台数据管理系统_第9张图片

 

PermissionHandleUtils.java

package com.jbz.utils;

import com.jbz.domain.User;
import com.jbz.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;

/**
 * @author: jbz
 * @date: 2023/1/9
 * @description:
 * @version: 1.0
 */
@Component
public class PermissionHandleUtils {
    //依赖注入
    @Autowired
    private IUserService userService;

    public Boolean judgePermissions(HttpServletRequest request,User user) {
        //获取用户的具有权限请求路径
        String[] permissionUrl = userService.queryUserPermissionsById(user.getId());
        //获得当前请求路径
        String requestURL = request.getRequestURI();
        //进行判断
        if (permissionUrl != null && permissionUrl.length != 0) {
            List list = Arrays.asList(permissionUrl);
            if (list.contains("/*")) {
                return true;
            } else if (list.contains(requestURL)) {
                return true;
            } else if (requestURL.equals("/favicon.ico")) {
                return true;
            } else return list.contains("/personal/*") && requestURL.contains("/personal/");
        } else {
            return false;
        }
    }
}

 PermissionInterceptor.java

package com.jbz.interceptor;

import com.jbz.constant.MessageConstant;
import com.jbz.domain.User;
import com.jbz.utils.PermissionHandleUtils;
import com.jbz.utils.RecordingLogUtils;
import com.jbz.utils.SetDataUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * @author: jbz
 * @date: 2023/1/9
 * @description: 用户权限拦截器(对用户的请求进行权限的监控与拦截)
 * @version: 1.0
 */
public class PermissionInterceptor implements HandlerInterceptor {
    @Autowired
    private PermissionHandleUtils permissionHandle;
    @Autowired
    private RecordingLogUtils recordingLog;
    @Autowired
    private SetDataUtils setDataUtil;
    //在目标方法之前执行
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //判断用户是否登录
        HttpSession session = request.getSession();
        //从session中获取用户
        User user = (User) session.getAttribute("user");
        //如果用户为null或者用户名为空
        if (user == null || "".equals(user.getUsername())) {
            //还停留在登录页
            response.sendRedirect(request.getContextPath() + "/pages/login.jsp");
            return false;
        } else {
            Boolean flag = permissionHandle.judgePermissions(request, user);
            if(flag){
                //放行
                return true;
            }else {
                setDataUtil.setPermissionCount(request.getSession());
                //添加日志
                recordingLog.insertSysLog(user.getUsername(), MessageConstant.EXECUTE_METHOD_FAIL,request.getRequestURI(),0,"方法已拦截");
                //跳转至错误页面
                response.sendRedirect(request.getContextPath() + "/pages/403.jsp");
                return false;
            }
        }
    }
}

七、Bcrypt加密算法

首先我们需要导入spring-security的依赖,如下所示,接着封装一个工具类用于返回一个BCryptPasswordEncoder并注册进IOC容器

 
        org.springframework.security
        spring-security-core
        5.0.5.RELEASE
 
@Component
public class MyPasswordEncoder {

    @Bean
    PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder(10);
    }
}

接着我们在servic业务层对应的实现类里依赖注入PasswordEncoder,在新增用户以及修改密码的时候,对密码进行加密,使用passwordEncoder.encode()对传入的密码进行加密,返回加密后的密码,将user对象的密码修改为加密后的密码,最后存入数据库中。在登录时进行密码解密与比对,同一个密码的加密结果也是不一样的,PasswordEncoder也有加盐处理,passwordEncoder.matches(password,encodePassword)对密码进行比对,返回boolean值。代码如下所示。

  @Override
    public void updatePersonalUser(User user) {
        //对密码进行加密处理
        String encodePassword = passwordEncoder.encode(user.getPassword());
        user.setPassword(encodePassword);
        userMapper.updateUser(user);
    }
 @Override
    public void addUser(User user, int[] roleIds) {
        //对密码进行加密处理
        String encodePassword = passwordEncoder.encode(user.getPassword());
        user.setPassword(encodePassword);
        userMapper.insertUser(user);
        userRoleMapper.insertUserRole(user.getId(), roleIds);
    }
  @Override
    public User login(String username, String password) {
        //调用userMapper的根据用户名查user的方法
        User user = userMapper.queryUserByUsername(username);
        //判断user是否为null
        if (user != null) {
            //判断密码是否一致
            if (passwordEncoder.matches(password,user.getPassword())) {
                return user;
            }
        }
        return null;
    }

八、总结

项目源码地址:GitHub - JBZ0805/ssm

项目运行效果如下图所示,

基于SSM框架实现后台数据管理系统_第10张图片

基于SSM框架实现后台数据管理系统_第11张图片 

基于SSM框架实现后台数据管理系统_第12张图片 

 

你可能感兴趣的:(mybatis,java-ee,spring,redis,mysql)