【SpringBoot搭建个人博客】- 后台登录(四)

博客地址:ONESTARの客栈

源码领取方式一:

  • 扫一扫文末二维码,关注公众号【编程日刊】,后台回复【博客】,即可领取源码

源码领取方式二:

欢迎给star以鼓励(^_−)☆

本文将从MVC架构、MD5加密、登录拦截器来讲述个人博客系统的后台登录实现

MVC架构

后台开发采用的是MVC架构,MVC 全名是 Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写, 是一种用于设计创建 Web 应用程序表现层的模式。MVC 中每个部分各司其职:

Model(模型):

  • 通常指的是我们的数据模型,一般情况下用于封装数据

View(视图):

  • 通常指 jsp 或者 html,一般用于展示数据,通常视图是依据模型数据创建的

Controller(控制器):

  • 应用程序中处理用户交互的部分,一般用于处理程序逻辑的

1.用户实体类

之前提到过,由于是个人博客,就没有做权限管理,只是简单的区分了一下管理员(栈主)和普通用户,所以这里需要用户实体类,并需要基本的用户名和密码,管理员登录后可以对后台进行操作,而普通用户则没有权限,在com.star(Group组名)目录下创建entity包,并创建User实体类,实体类如下(这里省去了get、set、toString方法):

package com.star.entity;

import java.util.Date;

/**
 * @Description: 用户实体类
 * @Date: Created in 21:39 2020/5/26
 * @Author: ONESTAR
 * @QQ群: 530311074
 * @URL: https://onestar.newstar.net.cn/
 */
public class User {

    private Long id;
    private String nickname;
    private String username;
    private String password;
    private String email;
    private String avatar;
    private Integer type;
    private Date createTime;
    private Date updateTime;

}
复制代码

2.MD5加密

由于后面要用到MD5加密,对登录密码进行加密,这里就先进行处理一下,在com.star包下创建util工具包,用来放工具类,创建MD5Utils工具类,如下:

package com.star.util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * @Description: MD5加密工具类
 * @Date: Created in 17:16 2020/5/27
 * @Author: ONESTAR
 * @QQ群: 530311074
 * @URL: https://onestar.newstar.net.cn/
 */
public class MD5Utils {

    /**
     * @Description: MD5加密
     * @Auther: ONESTAR
     * @Date: 17:19 2020/5/27 
     * @Param: 要加密的字符串
     * @Return: 加密后的字符串
     */
    public static String code(String str){
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(str.getBytes());
            byte[]byteDigest = md.digest();
            int i;
            StringBuffer buf = new StringBuffer("");
            for (int offset = 0; offset < byteDigest.length; offset++) {
                i = byteDigest[offset];
                if (i < 0)
                    i += 256;
                if (i < 16)
                    buf.append("0");
                buf.append(Integer.toHexString(i));
            }
            //32位加密
            return buf.toString();
            // 16位的加密
            //return buf.toString().substring(8, 24);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }

    }


    public static void main(String[] args) {
        System.out.println(code("111111"));
    }

}
复制代码

分析:

  • 通过该工具类,可以获取密码,在main函数中输入自己密码对应的明码,然后运行,可以在控制台获取对应的密码,这个密码是要存储在数据库中的password字段
  • eg:这里是"111111"字符串,运行main后,获得密码为:"96e79218965eb72c92a549dd5a330112",则将该字符串存储进数据库中

3.持久层接口

在com.star目录下创建dao包,创建用户持久层接口UserDao,这里主要查询用户名和密码,通过@Param注解将参数传递给SQL,代码如下:

package com.star.dao;

import com.star.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

/**
 * @Description: 用户持久层接口
 * @Date: Created in 0:06 2020/5/27
 * @Author: ONESTAR
 * @QQ群: 530311074
 * @URL: https://onestar.newstar.net.cn/
 */
@Mapper
@Repository
public interface UserDao {
    /**
     * @Description:
     * @Auther: ONESTAR
     * @Date: 10:24 2020/5/27
     * @Param: username:用户名;password:密码
     * @Return: 返回用户对象
     */
    User findByUsernameAndPassword(@Param("username") String username, @Param("password") String password);
}
复制代码

分析:

  • @Mapper注解:让Mybatis找到对应的mapper,在编译的时候动态生成代理类,实现相应SQL功能
  • @Repository注解:用来声明dao层的bean(这个注解可有可无,可以消去依赖注入的报错信息)【@Mapper和@Repository注解可以参考这篇文章:Mybatis 中的 @Repository 与 @Mapper
  • @Param注解:将参数传递给SQL
  • 返回一个User对象给service调用并核对用户名和密码

4.mapper

Mybatis使用XMLMMapperBuilder类的实例来解析mapper配置文件并执行SQL语句,在resources目录下创建mapper文件夹,再创建UserDao.xml文件,如下:

<?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.star.dao.UserDao">

    <!--查询用户名和密码-->
    <select id="findByUsernameAndPassword" resultType="com.star.entity.User">
        select * from myblog.t_user
        where username = #{username} and password = #{password};
    </select>

</mapper>

复制代码

5.用户业务层

在com.star目录下创建service包,创建用户业务层接口UserService,这里主要是检验用户名和密码,传递用户名和密码两个参数,代码如下:

package com.star.service;

import com.star.entity.User;

/**
 * @Description: 用户业务层接口
 * @Date: Created in 22:56 2020/5/26
 * @Author: ONESTAR
 * @QQ群: 530311074
 * @URL: https://onestar.newstar.net.cn/
 */
public interface UserService {
    //核对用户名和密码
    User checkUser(String username, String password);
}
复制代码

用户层接口实现类:

在service包下创建Impl包,用来放接口实现类,UserServiceImpl代码如下:

package com.star.service.Impl;

import com.star.dao.UserDao;
import com.star.entity.User;
import com.star.service.UserService;
import com.star.util.MD5Utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @Description: 用户业务层接口实现类
 * @Date: Created in 23:01 2020/5/26
 * @Author: ONESTAR
 * @QQ群: 530311074
 * @URL: https://onestar.newstar.net.cn/
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    /**
     * @Description:
     * @Auther: ONESTAR
     * @Date: 21:25 2020/5/27 
     * @Param: username:用户名;password:密码
     * @Return: 返回用户对象
     */
    @Override
    public User checkUser(String username, String password) {
        User user = userDao.findByUsernameAndPassword(username, MD5Utils.code(password));
        return user;
    }
}
复制代码

分析:

  • 这里主要是获取数据库中的用户名和密码,通过控制器传递过来的密码进行解析匹配,匹配成功则登录

6.登录控制器

在controller控制器包下创建admin包,用来放用户管理的控制器,创建LoginController用户登录控制器,在这里进行登录跳转、登录校验、注销功能,代码如下:

package com.star.controller.admin;

import com.star.entity.User;
import com.star.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpSession;

/**
 * @Description: 用户登录控制器
 * @Date: Created in 21:40 2020/5/27
 * @Author: ONESTAR
 * @QQ群: 530311074
 * @URL: https://onestar.newstar.net.cn/
 */
@Controller
@RequestMapping("/admin")
public class LoginController {

    @Autowired
    private UserService userService;

    /**
     * @Description: 跳转登录页面
     * @Auther: ONESTAR
     * @Date: 21:57 2020/5/27
     * @Param:
     * @Return: 返回登录页面
     */
    @GetMapping
    public String loginPage(){
        return "admin/login";
    }

    /**
     * @Description: 登录校验
     * @Auther: ONESTAR
     * @Date: 10:04 2020/5/27
     * @Param: username:用户名
     * @Param: password:密码
     * @Param: session:session域
     * @Param: attributes:返回页面消息
     * @Return: 登录成功跳转登录成功页面,登录失败返回登录页面
     */
    @PostMapping("/login")
    public String login(@RequestParam String username,
                        @RequestParam String password,
                        HttpSession session,
                        RedirectAttributes attributes) {
        User user = userService.checkUser(username, password);
        if (user != null) {
            user.setPassword(null);
            session.setAttribute("user",user);
            return "admin/index";
        } else {
            attributes.addFlashAttribute("message", "用户名和密码错误");
            return "redirect:/admin";
        }
    }

    /**
     * @Description: 注销
     * @Auther: ONESTAR
     * @Date: 10:15 2020/5/27
     * @Param: session:session域
     * @Return: 返回登录页面
     */
    @GetMapping("/logout")
    public String logout(HttpSession session) {
        session.removeAttribute("user");
        return "redirect:/admin";
    }
}
复制代码

分析:

  • @RequestMapping注解:映射请求路径
  • 登录校验:将前端传递过来的用户名和密码给service进行检验核对,并放入session域中(session是全局的,登录后访问其他页面或者重开页面也是登录状态)
  • 登录成功跳转后台管理页面,失败则跳转登录页面
  • 登录成功后可以进行注销,注销后返回登录页面

运行代码,访问:http://localhost:8080/admin/ ,输入用户名和密码,这里要注意先将密码进行MD5加密,将加密后的字符串存储进数据库。如下,登录成功,跳转到了后台管理页面

image

前端直接用thymeleaf模板处理,不做解说

7.登录拦截器

在没有登录的情况下,不能让游客访问到后台管理页面,在这里就需要加一个登录拦截器,将访问路径给过滤掉,这里就用SpringBoot里面内置的interceptor,在com.star包下新建interceptor包,创建LoginInterceptor登录过滤拦截器,继承HandlerInterceptorAdapter适配器,重写预处理方法,进行拦截,如下:

拦截器:

package com.star.interceptor;

import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @Description: 登录过滤拦截
 * @Author: ONESTAR
 * @Date: Created in 13:55 2020/3/27
 * @QQ群: 530311074
 * @URL: https://onestar.newstar.net.cn/
 */
public class LoginInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response,
                             Object handler) throws Exception {
//        判断session里面是否有用户,没有的话重定向到登录页面,给拦截掉
        if (request.getSession().getAttribute("user") == null) {
            response.sendRedirect("/admin");
            return false;
        }
        return true;
    }
}
复制代码

分析:

  • 继承HandlerInterceptorAdapter适配器,重写预处理方法preHandle
  • 对session进行判断,看是否有用户,没有的话重定向到登录页面,给拦截掉
  • 还需要指定拦截的内容

指定拦截内容:

同级包下新建WebConfig配置类,继承WebMvcConfigurerAdapter配置,重写addInterceptors过滤设置,如下:

package com.star.interceptor;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

/**
 * @Description: 指定拦截内容的配置类
 * @Author: ONESTAR
 * @Date: Created in 13:57 2020/3/27
 * @QQ群: 530311074
 * @URL: https://onestar.newstar.net.cn/
 */
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
                //过滤的路径
                .addPathPatterns("/admin/**")
                .excludePathPatterns("/admin")
                .excludePathPatterns("/admin/login");
    }
}
复制代码

分析:

  • @Configuration注解:表明是一个有效的配置类
  • 重写addInterceptors方法
  • 指定要拦截的路径,这里拦截"admin"访问路径

拦截器完成

按照MVC架构开发,后端MVC架构目录结构如下

image


至此,个人博客系统的后台登录功能实现完成,下一篇将讲述博客的分类管理

【点关注,不迷路,欢迎持续关注本站】

猜你喜欢

转载自juejin.im/post/5ecf1b11f265da76d40bf837