Java项目实战--瑞吉外卖DAY02

发布时间:2024年01月15日

P15完善登录功能_问题分析并创建过滤器

问题分析

代码实现

处理逻辑

P16

创建过滤器,添加注解 @WebFilter
?

添加

过滤器名称:filterName = "loginCheckFilter",

拦截路径:urlPatterns = "/*"

实现filter里的doFilter方法

LoginCheckFilter.java
package com.itheima.reggie.filter;

import lombok.extern.slf4j.Slf4j;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 检查用户是否已完成登录
 */
@Slf4j
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
public class LoginCheckFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest request= (HttpServletRequest) servletRequest;//强转
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        log.info("拦截到请求:{}",request.getRequestURI());
        filterChain.doFilter(request,response);
    }
}
在application.java添加@ServletComponentScan注解,这样才能去扫描我们的@WebFilter注解,从而把我们 的过滤器创建出来。

运行测试效果

P17完善登录功能_代码开发

首先将5个步骤复制到代码中,然后在根据每一步进行代码编写,这样的代码清晰易懂,每一行做好备注。

编写过滤器处理逻辑

前端JS中使用了响应拦截器,用来拦截服务的给页面上的响应的

后端也有一个

package com.itheima.reggie.filter;

import com.alibaba.fastjson.JSON;
import com.itheima.reggie.common.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 检查用户是否已完成登录
 */
@Slf4j
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
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
        //定义不需要处理的请求路径
        String[] urls= new String[]{
                "/employee/login", //表示点击的登录按钮 直接放行
                "/employee/logout", //表示点击的退出按钮 直接放行
                "/backend/**",//静态资源直接放行,页面没事 但是对应的数据 会发生ajax请求,无法访问。只拦截controller的请求。
                "/front/**"
        } ;

        //2、判断本次请求是否需要处理
        boolean check = check(urls, requestURI);//调用check方法  把urls和reqiestURI传进去

        // 3、如果不需要处理,则直接放行
        if (check){
            filterChain.doFilter(request,response);
            return;
        }
        // 4、判断登录状态,如果已登录,则直接放行
        //session中可以取出用户,不为空,则说明已经登录了
        if(request.getSession().getAttribute("employee") != null){
            filterChain.doFilter(request,response);
            return;
        }

        // 5、如果未登录则返回未登录结果,过输出流的方式向客户端响应数据
      response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));//NOTLOGIN取自backend中request.js响应拦截器里的
        return;
//        log.info("拦截到请求:{}",request.getRequestURI());
//        filterChain.doFilter(request,response);
    }

    /**路径匹配,检查本次请求是否需要放行
     *  把URLS传进来 遍历
     * @param urls
     * @param requestURI
     * @return
     */
    public boolean check(String[] urls,String requestURI){
        for (String url : urls) {
            boolean match = PATH_MATCHER.match(url, requestURI);
            if(match){
                return true;
            }
        }return false ;//匹配不上返回false
    }
}

P18 完善登录功能_功能测试

可以加一些日志,方便调试

测试1,不登陆 ,直接访问:localhost:8080/backend/index.html,可以看到效果,一闪而过的index页面就返回了登录首页。如果点击登录的话,就可以正常进入index页面了。

控制台会有拦截请求

也可以页面测试 F12-sources-request.js 加断点

汉语版

英文版,汉语版好理解,博主这里给大家展示英文版的

访问backend/index.html

显示如下

这个是单步调试

走一步 会显示

放行按钮

package com.itheima.reggie.filter;

import com.alibaba.fastjson.JSON;
import com.itheima.reggie.common.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 检查用户是否已完成登录
 */
@Slf4j
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
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/**",//静态资源直接放行,页面没事 但是对应的数据 会发生ajax请求,无法访问。只拦截controller的请求。
                "/front/**"
        } ;

        //2、判断本次请求是否需要处理
        boolean check = check(urls, requestURI);//调用check方法  把urls和reqiestURI传进去

        // 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("empliyee"));
            filterChain.doFilter(request,response);
            return;
        }

        // 5、如果未登录则返回未登录结果,过输出流的方式向客户端响应数据
        log.info("用户未登录");
         response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));//NOTLOGIN取自backend中request.js响应拦截器里的
        return;
//        log.info("拦截到请求:{}",request.getRequestURI());
//        filterChain.doFilter(request,response);
    }

    /**路径匹配,检查本次请求是否需要放行
     *  把URLS传进来 遍历
     * @param urls
     * @param requestURI
     * @return
     */
    public boolean check(String[] urls,String requestURI){
        for (String url : urls) {
            boolean match = PATH_MATCHER.match(url, requestURI);
            if(match){
                return true;
            }
        }return false ;//匹配不上返回false
    }
}

P19新增员工_需求分析和数据模型

P20新增员工_梳理程序执行流程

添加一些数据,点击保存,这一步,我们主要看请求发到哪里去了,消息是json形式的

P21新增员工_代码开发和功能测试’

先写一个框架,打上断点,然后测试

填上一些数据,点击保存

数据过来了

至此,证明心中数据是可以正常封装的,进行下一步

   //设置初始密码,但是要进行MD5加密
        employee.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));
 /**
     * 新增员工
     * 要返回json 所以添加@requestbody
     * @param employee
     * @return
     */
    @PostMapping
    public R<String> save(HttpServletRequest request,@RequestBody Employee employee){
        log.info("新增员工,员工信息:{}",employee);
        //设置初始密码,但是要进行MD5加密
        employee.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));
        //设置创建时间
        employee.setCreateTime(LocalDateTime.now());
        employee.setUpdateTime(LocalDateTime.now());
//        获得当前用户的ID 强转为LONG类型
        Long empId = (Long) request.getSession().getAttribute("employee");
        employee.setCreateUser(empId);
        employee.setUpdateUser(empId);
//        最后调用save方法进行存入
        employeeService.save(employee);

        return R.success("新增员工成功");
    }
}

代码测试

查看控制台insert语句

插入成功,时间就是当前时间,密码也是进行了MD5加密的123456

当我们在添加同一条姓名的数据时,报错

而这是最底层的数据库反馈的,稍后我们解决这个问题。

package com.itheima.reggie.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.itheima.reggie.common.R;
import com.itheima.reggie.entity.Employee;
import com.itheima.reggie.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;

@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {
    @Autowired
    private EmployeeService employeeService;
    /**
     *员工登录
     */
    @PostMapping("/login")
    public R<Employee> login(HttpServletRequest request, @RequestBody Employee employee){

        /**
         * 1、将页面提交的密码password进行md5加密处理
         * 2、根据页面提交的用户名username查询数据库
         * 3、如果没有查询到则返回登录失败结果
         * 4、密码比对,如果不一致则返回登录失败结果
         * 5、查看员工状态,如果为已禁用状态,则返回员工已禁用结果
         * 6、登录成功,将员工id存入Session并返回登录成功结果
         */

        //         * 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());
        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);
    }

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


    /**
     * 新增员工
     * 要返回json 所以添加@requestbody
     * @param employee
     * @return
     */
    @PostMapping
    public R<String> save(HttpServletRequest request,@RequestBody Employee employee){
        log.info("新增员工,员工信息:{}",employee);
        //设置初始密码,但是要进行MD5加密
        employee.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));
        //设置创建时间
        employee.setCreateTime(LocalDateTime.now());
        employee.setUpdateTime(LocalDateTime.now());
//        获得当前用户的ID 强转为LONG类型
        Long empId = (Long) request.getSession().getAttribute("employee");
        employee.setCreateUser(empId);
        employee.setUpdateUser(empId);
//        最后调用save方法进行存入
        employeeService.save(employee);

        return R.success("新增员工成功");
    }
}

P22新增员工_编写全局异常处理器

day01链接:Java项目实战--瑞吉外卖DAY01-CSDN博客

持续更新中---------------------------------------------------------------------------

文章来源:https://blog.csdn.net/Fxdll/article/details/135589036
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。