java项目实战–瑞吉外卖Day2


文章目录

  • java项目实战--瑞吉外卖Day2
  • 一、完善登录功能
  • 1.问题分析
  • 2.创建过滤器
  • 3.完善过滤器处理逻辑
  • 二、新增员工功能
  • 1.数据模型
  • 2.新增员工代码开发
  • 3.全局异常处理器
  • 4.新增员工_小结
  • 三、员工信息分页查询
  • 1.需求分析
  • 2.代码开发
  • 四、启用/禁用员工账户
  • 1.需求分析
  • 2.代码开发
  • 3.功能测试
  • 五、编辑员工信息
  • 1.需求分析
  • 2.代码开发


一、完善登录功能

1.问题分析

互联网java高级架构设计 互联网公司java实战项目_servlet

2.创建过滤器

1.创建过滤器步骤:

互联网java高级架构设计 互联网公司java实战项目_spring boot_02


2.具体实现:

首先在ReggieApplication.java类中添加ServletComponentScan注解:

互联网java高级架构设计 互联网公司java实战项目_spring boot_03


接着创建filter包,在包中创建LoginCheckFilter类:

互联网java高级架构设计 互联网公司java实战项目_互联网java高级架构设计_04


LoginCheckFilter类的代码如下:

package com.mj.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;

/**
 * @author mj
 * @version 1.0
 * 检查用户是否已经完成登录
 */
@WebFilter(filterName = "loginCheckFilter", urlPatterns = "/*")
@Slf4j
public class LoginCheckFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        log.info("拦截到请求: {}", httpServletRequest.getRequestURI());
        filterChain.doFilter(httpServletRequest,response);
    }
}

3.完善过滤器处理逻辑

1.过滤器具体的处理逻辑图:

互联网java高级架构设计 互联网公司java实战项目_java_05


2.在LoginCheckFilter类中完善过滤器具体的处理逻辑,代码如下:

package com.mj.reggie.filter;

import com.alibaba.fastjson.JSON;
import com.mj.reggie.common.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.servlet.server.Session;
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;

/**
 * @author mj
 * @version 1.0
 * 检查用户是否已经完成登录
 */
@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 httpServletRequest = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
//        1.获取本次请求的URI
        String requestURI = httpServletRequest.getRequestURI();
        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(httpServletRequest, response);
            return;
        }
//        4.判断登录状态,如果已登录,则直接放行
        if (httpServletRequest.getSession().getAttribute("employee") != null) {
            log.info("用户已登录,用户ID为:{}", httpServletRequest.getSession().getAttribute("employee"));
            filterChain.doFilter(httpServletRequest, response);
            return;
        }
        log.info("用户未登录");
//        5.如果未登录则返回未登录结果,通过输出流方式向页面返回响应数据
        response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
        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;
    }
}

二、新增员工功能

1.数据模型

互联网java高级架构设计 互联网公司java实战项目_servlet_06

互联网java高级架构设计 互联网公司java实战项目_互联网java高级架构设计_07

2.新增员工代码开发

互联网java高级架构设计 互联网公司java实战项目_互联网java高级架构设计_08


在EmployeeController类中编写save方法实现新增员工功能,代码如下:

/*
     * 新增员工
     * */
    @PostMapping
    public R<String> save(HttpServletRequest request, @RequestBody Employee employee) {
        log.info("新增员工,员工信息:{}", employee.toString());
//        设置初始密码123456,需要进行MD5加密
        employee.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));

//        当前创建时间和更新时间
        employee.setCreateTime(LocalDateTime.now());
        employee.setUpdateTime(LocalDateTime.now());

//        获取当前登录用户的ID
        Long empId = (Long) request.getSession().getAttribute("employee");
        employee.setCreateUser(empId);
        employee.setUpdateUser(empId);
        employeeService.save(employee);
        return R.success("新增员工成功");
    }
}
## 2.读入数据

代码如下(示例):

```c
data = pd.read_csv(
    'https://labfile.oss.aliyuncs.com/courses/1283/adult.data.csv')
print(data.head())

3.全局异常处理器

互联网java高级架构设计 互联网公司java实战项目_互联网java高级架构设计_09


在com.mj.reggie.common包中新建一个GlobalExceptionHandler类作为全局异常处理器类:

互联网java高级架构设计 互联网公司java实战项目_maven_10


代码如下:

package com.mj.reggie.common;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.sql.SQLIntegrityConstraintViolationException;

/**
 * @author mj
 * @version 1.0
 * 全局异常处理
 */
@ControllerAdvice(annotations = {RestController.class, Controller.class})
@Slf4j
@ResponseBody
public class GlobalExceptionHandler {

    @ExceptionHandler(SQLIntegrityConstraintViolationException.class)
    public R<String> exceptionHandler(SQLIntegrityConstraintViolationException ex) {
        log.info(ex.getMessage());
        if (ex.getMessage().contains("Duplicate entry")) {
            String[] strings = ex.getMessage().split(" ");
            String msg = strings[2] + "已存在";
            return R.error(msg);
        }
        return R.error("未知错误");

    }
}

4.新增员工_小结

互联网java高级架构设计 互联网公司java实战项目_spring boot_11

三、员工信息分页查询

1.需求分析

互联网java高级架构设计 互联网公司java实战项目_互联网java高级架构设计_12

2.代码开发

互联网java高级架构设计 互联网公司java实战项目_maven_13

1.在实现功能之前,我们需要先配置mybatisplus的分页插件,在com.mj.reggie.config包中创建一个MybatisPlusConfig类:

互联网java高级架构设计 互联网公司java实战项目_java_14


代码如下:

package com.mj.reggie.config;

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author mj
 * @version 1.0
 * 配置MP的分页插件
 */

@Configuration
public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return mybatisPlusInterceptor;
    }
}

2.在EmployeeController类中创建page方法实现员工信息分页查询功能,代码如下:

/*
     * 员工信息分页查询
     * */
    @GetMapping("/page")
    public R<Page> page(int page, int pageSize, String name) {
        log.info("page = {},pageSize = {},name = {}", page, pageSize, name);
//        构造分页构造器
        Page pageInfo = new Page(page, pageSize);
//        构造条件构造器
        LambdaQueryWrapper<Employee> lambdaQueryWrapper = new LambdaQueryWrapper();
//        添加过滤条件
        lambdaQueryWrapper.like(StringUtils.isNotEmpty(name), Employee::getName, name);
//        添加排序条件
        lambdaQueryWrapper.orderByDesc(Employee::getUpdateTime);
//        执行查询
        employeeService.page(pageInfo, lambdaQueryWrapper);
        return R.success(pageInfo);

    }
}

四、启用/禁用员工账户

1.需求分析

互联网java高级架构设计 互联网公司java实战项目_maven_15


互联网java高级架构设计 互联网公司java实战项目_servlet_16


互联网java高级架构设计 互联网公司java实战项目_spring boot_17

2.代码开发

互联网java高级架构设计 互联网公司java实战项目_spring boot_18


页面中的ajax请求发送流程如下:

互联网java高级架构设计 互联网公司java实战项目_maven_19


互联网java高级架构设计 互联网公司java实战项目_互联网java高级架构设计_20


在EmployeeController类中创建update方法实现根据员工ID修改员工信息功能,代码如下:

/*
     * 根据ID修改员工信息
     * */
    @PutMapping
    public R<String> update(HttpServletRequest request, @RequestBody Employee employee) {
        log.info(employee.toString());
        Long empId = (Long) request.getSession().getAttribute("employee");
        employee.setUpdateTime(LocalDateTime.now());
        employee.setUpdateUser(empId);
        employeeService.updateById(employee);

        return R.success("员工信息修改成功");
    }

3.功能测试

在进行功能测试时发现功能并没有实现,

互联网java高级架构设计 互联网公司java实战项目_servlet_21

原因是js对long型数据进行处理时丢失精度,导致提交的id和数据库中的id不一致。

互联网java高级架构设计 互联网公司java实战项目_互联网java高级架构设计_22


而想要解决这个问题,就需要我们将long型数据统一转换成String字符串,具体操作如下:

互联网java高级架构设计 互联网公司java实战项目_java_23


先将资料中提供的对象转化器类JacksonObjectMapper拷贝到com/mj/reggie/common包中:

互联网java高级架构设计 互联网公司java实战项目_互联网java高级架构设计_24


然后在WebMvcConfig类中创建extendMessageConverters方法以扩展MVC框架的消息转换器,代码如下:

/*
     * 扩展MVC框架的消息转换器
     * */

    @Override
    protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
//        创建消息转换器对象
        MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
//        设置对象转换器,底层使用Jackson将Java对象转为json
        messageConverter.setObjectMapper(new JacksonObjectMapper());
//        将上面的消息转换器对象追加到mvc框架的转换器集合中
        converters.add(0, messageConverter);
    }
}

五、编辑员工信息

1.需求分析

互联网java高级架构设计 互联网公司java实战项目_spring boot_25

2.代码开发

互联网java高级架构设计 互联网公司java实战项目_servlet_26

为了让用户信息回显到编辑页面:

互联网java高级架构设计 互联网公司java实战项目_maven_27


我们需要编写getById方法来查询员工信息并返回,代码如下:

/*
     * 根据id查询员工信息
     * */
    @GetMapping("/{id}")    // 接收URL地址上的参数Id用  /{id} 写法
    //    @PathVariable 是路径变量,表示id这个参数在请求路径里
    public R<Employee> getById(@PathVariable Long id) {
        log.info("根据id查询员工信息...");
//        根据id查询员工信息并通过employee对象返回
        Employee employee = employeeService.getById(id);
        if (employee != null){
            return R.success(employee);
        }
        return R.error("没有查询到对应员工信息");
    }
}

返回之后修改员工信息时所使用的方法就是我们之前写好的update方法。