后台登录功能开发 — 手把手教你做ssm+springboot入门后端项目黑马程序员瑞吉外卖(二)

得意时要看淡,失意时要看开。不论得意失意,切莫大意;不论成功失败,切莫止步。志得意满时,需要的是淡然,给自己留一条退路;失意落魄时,需要的是泰然,给自己觅一条出路后台登录功能开发 — 手把手教你做ssm+springboot入门后端项目黑马程序员瑞吉外卖(二),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文


前言

为了巩固所学的知识,作者尝试着开始发布一些学习笔记类的博客,方便日后回顾。当然,如果能帮到一些萌新进行新技术的学习那也是极好的。作者菜菜一枚,文章中如果有记录错误,欢迎读者朋友们批评指正。
(博客的参考源码可以在我主页的资源里找到,如果在学习的过程中有什么疑问欢迎大家在评论区向我提出)

一、后台登录功能开发

1. 需求分析

1. 页面原型展示

在这里插入图片描述

2. 登录页面展示

在这里插入图片描述

3. 查看登录请求信息

  • 通过浏览器调试工具 (F12),可以发现,点击登录按钮时,页面会发送请求 (请求地址为http://localhost:8080/employee/login)并提交参数 (username和password)
  • 此时报404,是因为我们的后台系统还没有响应此请求的处理器,所以我们需要创建相关类来处理登录请求

在这里插入图片描述

4. 数据模型(employee表)

employee表存储管理员工的信息,对比员工的用户名密码进行登录操作

在这里插入图片描述

在这里插入图片描述

2. 代码开发

1. 创建实体类包entity,并创建实体类Employee,和employee表进行映射

/**
 * 员工实体
 */
@Data
public class Employee implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;

    private String username;

    private String name;

    private String password;

    private String phone;

    private String sex;

    private String idNumber;//身份证号码

    private Integer status;

    private LocalDateTime createTime;

    private LocalDateTime updateTime;

    @TableField(fill = FieldFill.INSERT)
    private Long createUser;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Long updateUser;

}

2. 创建Controller、Service、Mapper

  • Mapper
@Mapper
public interface EmployeeMapper extends BaseMapper<Employee>{
}
  • Service

Service接口

public interface EmployeeService extends IService<Employee> {
}

ServiceImpl

@Service
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper,Employee> implements EmployeeService{
}
  • Controller
@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {

    @Autowired
    private EmployeeService employeeService;

}

3. 创建返回结果类(前后端约定)

  • 前端页面处理数据模型分析

在这里插入图片描述

  • 后端数据模型设计示例
/**
 * 通用返回结果,服务端响应的数据最终都会封装成此对象
 * @param <T>
 */
@Data
public class R<T> {

    private Integer code; //编码:1成功,0和其它数字为失败

    private String msg; //错误信息

    private T data; //数据

    private Map map = new HashMap(); //动态数据

    //登录成功,返回code = 1,并返回数据
    public static <T> R<T> success(T object) {
        R<T> r = new R<T>();
        r.data = object;
        r.code = 1;
        return r;
    }

    //登录失败,返回code = 0,并返回错误信息msg
    public static <T> R<T> error(String msg) {
        R r = new R();
        r.msg = msg;
        r.code = 0;
        return r;
    }

    public R<T> add(String key, Object value) {
        this.map.put(key, value);
        return this;
    }

}

此类是一个通用结果类,服务端响应的所有结果最终都会包装成此种类型返回给前端页面

4. 在controller中创建登录方法

处理逻辑如下:

  1. 将页面提交的密码password进行md5加密处理
  2. 根据页面提交的用户名username查询数据库
  3. 如果没有查询到则返回登录失败结果
  4. 密码比对,如果不一致则返回登录失败结果
  5. 查看员工状态,如果为已禁用状态(锁定字段status,1为正常,0为锁定),则返回员工已禁用结果
  6. 登录成功,将员工id存入Session并返回登录成功结果
@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {

    @Autowired
    private EmployeeService employeeService;

    /**
     * 员工登录
     * @param request
     * @param employee
     * @return
     */
    @PostMapping("/login")
    //@RequestBody:封装json数据
    //登录成功后员工的id存放在session中,通过request对象可以获取session,进一步获取用户信息
    public R<Employee> login(HttpServletRequest request,@RequestBody Employee employee){

        //1、将页面提交的密码password进行md5加密处理
        String password = employee.getPassword();
        password = DigestUtils.md5DigestAsHex(password.getBytes());

        //2、根据页面提交的用户名username查询数据库
        LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
        //等值条件查询
        queryWrapper.eq(Employee::getUsername,employee.getUsername());
        //由于在设计表的时候用户名字段索引类型设置为了Unique,查出来的是唯一对象,所以此处调用的是getOne方法
        Employee emp = employeeService.getOne(queryWrapper);

        //3、如果没有查询到则返回登录失败结果
        if(emp == null){
            return R.error("登录失败");
        }

        //4、密码比对,如果不一致则返回登录失败结果
        if(!emp.getPassword().equals(password)){
            return R.error("登录失败");
        }

        //5、查看员工状态,如果为已禁用状态,则返回员工已禁用结果
        if(emp.getStatus() == 0){
            return R.error("账号已禁用");
        }

        //6、登录成功,将员工id存入Session并返回登录成功结果
        request.getSession().setAttribute("employee",emp.getId());
        return R.success(emp);
    }

}

3. 功能测试(简略)

  • 运行启动类及项目结构示例

在这里插入图片描述

  • 在浏览器访问登录页面,输入用户名admin和密码123456

在这里插入图片描述

  • 点击登录

在这里插入图片描述

  • 后端页面渲染浅析

在这里插入图片描述

二、后台退出功能开发

1. 需求分析

  • 员工登录成功后,页面跳转到后台系统首页面(backend/index.html),此时会显示当前登录用户的姓名

  • 如果员工需要退出系统,直接点击右侧的退出按钮即可退出系统,退出系统后页面应跳转回登录页面

在这里插入图片描述

2. 代码开发

用户点击页面中退出按钮,发送请求,请求地址为/employee/logout,请求方式为POST.我们只需要在Controller中创建对应的处理方法即可,具体的处理逻辑:

  1. 清理Session中的用户id
  2. 返回结果
@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {

    @Autowired
    private EmployeeService employeeService;
    
    /**
     * 员工退出
     * @param request
     * @return
     */
    @PostMapping("/logout")
    public R<String> logout(HttpServletRequest request){
        //清理Session中保存的当前登录员工的id
        request.getSession().removeAttribute("employee");
        return R.success("退出成功");
    }
}

3. 功能测试(简略)

先登录,再点击退出

在这里插入图片描述

三、登录页面功能完善

1. 问题分析

  • 前面我们已经完成了后台系统的员工登录功能开发,但是还存在一个问题:用户如果不登录,直接访问系统首页面,照样可以正常访问。
  • 这种设计并不合理,我们希望看到的效果应该是,只有登录成功后才可以访问系统中的页面,如果没有登录则跳转到登录页面。
  • 那么,具体应该怎么实现呢?
    答案就是使用过滤器或者拦截器,在过滤器或者拦截器中判断用户是否已经完成登录,如果没有登录则跳转到登录页面。

2. 代码实现

1. 实现步骤

  1. 创建自定义过滤器LoginCheckFilter
  2. 在启动类上加入注解@ServletComponentScan
  3. 完善过滤器的处理逻辑

2. 过滤器处理逻辑

  1. 获取本次请求的URI
  2. 判断本次请求是否需要处理
  3. 如果不需要处理,则直接放行
  4. 判断登录状态,如果已登录,则直接放行
  5. 如果未登录则返回未登录结果

在这里插入图片描述

3. 结合前端相关js文件进行代码编写

  • 前端js处理逻辑分析

在这里插入图片描述

  • 创建filter包,并创建编写过滤器类LoginCheckFilter
/**
 * 检查用户是否已经完成登录
 */
//名称+拦截路径
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
@Slf4j
public class LoginCheckFilter implements Filter{
    //路径匹配器,支持通配符
    public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        //1、获取本次请求的URI
        String requestURI = request.getRequestURI();// /backend/index.html

        log.info("拦截到请求:{}",requestURI);

        //定义不需要处理的请求路径
        String[] urls = new String[]{
                "/employee/login",
                "/employee/logout",
                "/backend/**",
                "/front/**"
        };


        //2、判断本次请求是否需要处理
        boolean check = check(urls, requestURI);

        //3、如果不需要处理,则直接放行
        if(check){
            log.info("本次请求{}不需要处理",requestURI);
//            放行
            filterChain.doFilter(request,response);
            return;
        }

        //4、判断登录状态,如果已登录,则直接放行
//        从session中取出用户,能取出来不为空则为登录
        if(request.getSession().getAttribute("employee") != null){
            log.info("用户已登录,用户id为:{}",request.getSession().getAttribute("employee"));
            filterChain.doFilter(request,response);
            return;
        }

        log.info("用户未登录");
        //5、如果未登录则返回未登录结果,通过输出流方式向客户端页面响应数据
        response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
        return;

    }

    /**
     * 路径匹配,检查本次请求是否需要放行
     * @param urls
     * @param requestURI
     * @return
     */
    public boolean check(String[] urls,String requestURI){
//        是否匹配到url中的数组元素,能则放行
        for (String url : urls) {
//            match:匹配方法
            boolean match = PATH_MATCHER.match(url, requestURI);
            if(match){
                return true;
            }
        }
        return false;
    }
}

  • 在启动类上添加**@ServletComponentScan**注解
...
@ServletComponentScan
public class ReggieApplication {
   ...
}

3. 功能测试(简略)

1. 运行启动类ReggieApplication及代码文件结构参考

在这里插入图片描述

2. 不登录直接访问后台首页

在这里插入图片描述

我们发现页面跳转回了登录页面

3. 再次查看控制台

在这里插入图片描述

总结

欢迎各位留言交流以及批评指正,如果文章对您有帮助或者觉得作者写的还不错可以点一下关注,点赞,收藏支持一下。
(博客的参考源码可以在我主页的资源里找到,如果在学习的过程中有什么疑问欢迎大家在评论区向我提出)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之家整理,本文链接:https://www.bmabk.com/index.php/post/156718.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之家——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!