【Java】瑞吉外卖项目开发笔记

文章目录


一、项目概述

1.访问

  • http://172.17.0.60:8200/backend/index.html
  • http://172.17.0.60:8200/front/index.html

2.项目概述

2.1 APP移动端的应用:提供给餐厅的;

2.2 后台:对于菜品、套餐的维护;

3.软件开发整体介绍

3.1 软件开发流程

3.1.1 需求分析:产品原型,需求规格说明书的编写;

(1) 产品原型:通过网页的形式展现一下,当前开发项目的大体结构——涉及到的页面以及页面的结构样式,点击按钮之后需要查询哪些数据,产生什么样的效果,通过网页的形式直观的展现出来;
(2) 需求规格说明书:一个Word文档,展现这个项目都有哪些功能,需要有文字说明;

3.1.2 设计:基于上述“需求分析”,进行相应的设计工作(产品文档、UI界面设计、概要设计、详细设计、数据库设计)

(1) UI界面设计:需要把项目的界面效果展现出来;
(2) 数据库设计:需要设计出当前开发项目会用到几个数据库,每个数据库里面涉及到哪些表,具体到表的字段是什么样子的,都需要详细的把它设计出来。

3.1.3 编码:进入编码阶段(项目代码、单元测试)
3.1.4 测试:编码完成之后,进入测试阶段(测试用例、测试报告)
  • 由测试人员编写一些测试用例,然后出具一份测试报告;
3.1.5 上线运维:测试报告没有问题之后,便可以上线运维了,由专门的运维人员来完成,包括软件环境安装、配置、部署项目等。

3.2 角色分工(开发软件需要涉及到的开发团队和人员)

3.2.1 项目经理:对整个项目负责,任务分配、把控进度;属于管理人员。对于一些比较大的公司,项目经理不会参于具体的编码、文档的编写,主要对整个项目人员的调配、任务分配、资源调度等等。
3.2.2 产品经理:进行需求调研,输入需求调研文档、产品原型等;一般在项目前期,产品经理就会介入;
3.2.3 UI设计师:根据产品原型输出界面效果图;
3.2.4 架构师:项目整体架构设计、技术选型等;
3.2.5 开发工程师:代码实现;
3.2.6 测试工程师:编写测试用例,输出测试报告;
3.2.7 运维工程师:软件环境搭建、项目上线;一般项目开发完之后,运维工程师才会介入;

3.3 软件环境

(1) 开发环境(development):开发人员在开发阶段使用的环境,一般外部用户无法访问。(比如:开发人员使用的MySQL数据库,有可能是安装在开发人员本地电脑上的,或者在另外一台外部服务器上);

(2) 测试环境(testing):专门测试人员使用的环境,用于测试项目,一般外部用户无法访问。(专门供测试人员使用的测试服务器,上面安装了JDK、Tomcat等等在测试环境下使用到的软件);

(3) 生产环境(production):即上线环境,正式提供对外服务的环境。(项目上线所运行的环境,);

4.吉瑞外卖项目介绍

4.1 项目介绍(从功能需求方面介绍)

(1) 本项目(瑞吉外卖)是专门为餐饮企业(餐厅、饭店)定制的一款产品,包括系统管理后台和移动端应用两部分。其中系统管理后台主要提供给餐饮企业内部员工使用,可以对餐厅的菜品、套餐、订单等进行管理维护。移动端应用主要提供给消费者使用,可以在线浏览菜品、添加购物车、下单等等。

(2) 本项目共分为3期进行开发:

  • 第一期:主要实现基本需求,其中移动端应用通过H5实现,用户可以通过手机浏览器访问;
  • 第二期:主要针对移动端应用进行改进,使用微信小程序实现,用户使用起来更加方便;
  • 第三期:主要针对系统进行优化升级,提高系统的访问性能。

4.2 产品原型展示(通过网页的形式直观地展示出来,具体都有哪些功能、页面、页面结构等等);

4.3 技术选型(开发过程中,需要使用哪些技术栈)

4.4 功能架构(以图形化的方式展示出这个项目都有哪些功能)

4.5 角色(分析使用这个项目的人,都有哪几类人,再通过角色的方式对这些人进行一个划分)

4.5.1 产品原型展示

(1) 产品原型,就是一款产品成型之前的一个简单的框架,就是将页面的排版布局展现出来,使产品的初步构思有一个可视化的展示。通过原型展示,可以更加直观的了解项目的需求和提供的性能。

(2) 一般产品原型都是一些HTML页面,通过这些简单的页面了解到这个网站一些大概的效果。

(3) 课程资料中已经提供了产品原型:瑞吉外卖后台(管理端)和瑞吉外卖前台(用户端)

(4) 注意:产品原型主要用于展示项目的功能,并不是最终的页面效果;

4.5.2 技术选型

技术选型

4.5.3 功能架构

功能架构

4.5.4 角色
  • 后台系统管理员:登录后台管理系统,拥有后台系统中的所有操作权限;
  • 后台系统普通员工:登录后台管理系统,对菜品、套餐、订单等进行管理;
  • C端用户:登录移动端应用,可以浏览菜品、添加购物车、设置地址、在线下单等;

二、项目基础环境搭建

1.开发环境搭建

1.1 数据库环境搭建

1.1.1 创建对应的数据库(图形界面或者命令行都可以)

创建对应的数据库

1.1.2 导入表结构(资料/数据模型/db_reggle.sql)

导入表结构
方法一: 在数据库软件(图形界面)上找到数据库点右键→运行sql文件→找到sql文件的路径→确定;

方法二: 在dos窗口下: win+R → 新建数据库/使用数据库 → 输入 source → 然后将需要的.sql文件拖入到source后面,就会自动生成一个.sql文件的路径;

注意事项:
     ① 导入表结构,既可以使用上面的图形界面,也可以使用MySQL命令:
在这里插入图片描述
     ② 通过命令导入表结构时,注意sql文件不要放在中文目录中。

1.1.3 数据表

数据表
(1) 员工表 employee:存储员工的数据信息,包括姓名、密码等等;

(2) 菜品和套餐分类表 category:荤菜、素菜、凉菜

1.2 Maven项目搭建

1.2.1 创建Maven项目

创建Maven项目

  • 打开IDEA → New Project → GroupId : com.itheima → ArtifactId : reggie_tack_out
  • 注意事项:创建完项目后,注意检查项目的编码、Maven仓库配置、JDK配置等。
1.2.2 导入pom.xml文件 (位置:资料/项目配置文件/pom.xml)

导入pom.xml文件
pom.xml文件内容介绍:

    ① <parent>标签

<parent>  // 继承
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId> // 继承的名称
	<version>2.4.5</version>  // 继承的版本号
	<relativePath/> <!-- lookup parent from repository -->
</parent>

    ② <properties> 指定JDK的版本号

<properties>
   <java.version>1.8</java.version>
</properties>

    ③ <dependencies></dependencies>里面包含项目所依赖的Maven坐标,也就是各种jar包

  • spring-boot-starter 它能将模块所需的依赖整合起来并对模块内的Bean根据环境( 条件)进行自动配置。使用者只需要依赖相应功能的Starter,无需做过多的配置和依赖,Spring Boot就能自动扫描并加载相应的模块。
  • spring-boot-starter-test 做单元测试的
  • spring-boot-starter-web web应用需要的
  • mybatis-plus-boot-starter
  • lombok
  • fastjson Java对象转json的
  • commons-lang
  • mysql-connector-java mysql驱动包
  • druid-spring-boot-starter 阿里的数据源,数据库连接时使用的包

    ④ <build></build>插件

1.2.3 导入Spring Boot 配置文件(resources目录,在src→main→resources) application.yml (位置:资料/项目配置文件/application.yml),对于这些配置文件直接拿过来使用就行;

(1) 做法:找到application.yml文件,复制,在IDEA中找到src→main→resources目录,单击resources目录后,Ctrl+V粘贴即可;
在这里插入图片描述
(2) 解析:

  • server: port:8080 → tomcat的端口号
  • spring: application: name:cache_demo → 指定应用的名称,可选

在这里插入图片描述

  • 数据源相关的配置

在这里插入图片描述

1.2.4 编写启动类(Application.java)

Application.java
做法: 在main目录 → java目录 → 新建包com.itheima.reggie → 在这个包下新建启动类:ReggieApplication.java

在这里插入图片描述

1.2.5 (导入前端资源)下一步就是把涉及到前端的页面导入进来,因为主要为了练习java,所以前端内容直接导入。(目录 瑞吉点餐项目>前端>前端资源,里面有两个目录backend后端,里面是后台所涉及到的HTML页面;front前端,也就是移动端所涉及到的HTML页面)

(1) 将backend和front这两个文件夹复制一下,粘贴到项目的resources目录下;

  • 注意:对于我们引入的一些静态资源,默认是放到static和templet文件夹下面,所以放到backend和front这两个文件夹直接访问是访问不到的,所以需要将服务器停掉,重新开启就可以访问了……
  • 举例:访问一下backend文件夹下的index.html页面,localhost:8080/backend/index.html:

在这里插入图片描述

  • 这样会出现404页面,原因就是默认访问的是static和templet文件夹下的静态资源,需要通过编写配置类的方式来设置静态资源的映射(编写一个配置MVC的静态资源框架,来做静态资源的映射):在com.itheima → reggie目录下新建包config,以后所有的配置类都放在这个包下 → 新建配置类 WebMvcConfig.java,如图:

在这里插入图片描述
在这里插入图片描述

  • 释义:

        ① @Configuration 用来声明是配置类的

        ② @Slf4j 记录一个日志,方便调试

        ③ 目的:让它重新映射到backend目录下的index.html,这样就能访问到了

        ④ 通过通配符“/”的方式映射到相应的路径下

        ⑤ 用 registry 来设置哪些访问路径

        ⑥ addResourceHandler 资源处理器:处理前端发过来的请求是什么样子的

(2) 完成上面配置类后到RoggieApplication.java页面重新启动一下:
RoggieApplication.java
在下面看到“开始进行静态资源映射”的字样就说明上面写的配置类已经生效了。

在这里插入图片描述
到页面中重新输入网址就看到已经成功了……

(3) 到这里,项目的基础环境就已经搭建好了,在这基础之上就可以开发相应的业务功能了。


三、项目功能开发

1.后台登录功能开发

1.1 概述:从三个方面来入手:需求分析,代码开发,功能测试;

1.2 需求分析

1.2.1 页面原型展示

在这里插入图片描述
(1) 登录功能分析:就是在登录页面上输入用户名和密码,点击登录按钮,它就会发送请求,最终这个请求就会请求到服务端的一些组件,比如说先请求到controller 控制层,然后再通过controller层调service层,再调mapper,最终跟数据库交互,来根据我们的用户名和密码进行查询。—— 这就是我们的登录页面原型。

(2) 登录页面展示(页面位置:项目/resources/backend/page/login/login.html)
前面在进行项目搭建的时候,将项目页面一次性的导入进来了,所以这里在项目中找到注册登录页面login.html:
因为前面已经将backend和front目录放到“静态资源映射”里面了,所以可以直接访问到login.html页面(resources>backend>page>login>login.html),访问。

在这里插入图片描述

  • localhost:8080/backend/page/login/login.html

在这里插入图片描述
(3) 查看登录请求信息:

在浏览器中输入用户名和密码(用户名admin,密码是123456),点击登录按钮之后,会发生什么事情呢?

注意:在数据库reggie的员工表employee中可以看到用户名和密码,注意在表格里显示的密码是经过md5加密的,编译过来就是123456。

在浏览器登录页面上,按键盘F12键,调出调试工具,然后在输入用户名和密码,点击登录按钮之后,会看到页面显示“系统接口404异常”,这是因为我们后端服务还没开发的原因,所以在这里请求发出去之后,服务端没有去相应它造成报了404,在这里先不用去管它;

在这里先看点击登录按钮之后,在F12调出的调试页面中,查看它请求到哪里去了?如图:

在这里插入图片描述
可以看到,请求到了employee/login下面了,并且将我们的用户名和密码以json的形式(字符串的形式),给我们提交到了服务端,

总结:通过浏览器调试工具(F12),可以发现,页面会发送请求(请求地址为http://localhost:8080/employee/login)并提交参数(username和password)

此时报404,是因为我们的后台系统还没有响应此请求的处理器,所以我们需要创建相关类来处理登录请求;
在这里插入图片描述
(4) 数据库模型(employee表,即员工表)
在这里插入图片描述
登录页面对应的就是这张员工表;

(5) 回到IDEA中,找到登录页面(resources>backend>page>login>login.html),
大致浏览一下login.html页面,不一定会写,但一定要看懂:
在这里插入图片描述
VUE知识点:

  • el: → 指定我们唯一标识;在上面肯定有一个
    的id与之相对应;
    在这里是el:’#login-app’和上面
    相对应;
  • data(){} → 里面是我们需要用到的一些表单数据;
  • methods:{} → js里的方法;
  • handleLogin(){}方法:指的是当我们点击登录按钮的时候,它就会调用;即点击〔@click.native.prevent=”handleLogin”>登录〕时,就会触发handleLogin方法,

在这里插入图片描述
    ① 通过$refs语法找到表单loginForm,然后调用validate做一个校验,校验用户名密码是否为空;

    ② 如果校验通过,就把loading改为true,即“登录”和“登录中”的切换;
在这里插入图片描述

    ③ 校验通过之后,就调用loginApi这个方法,这个方法封装在一个js文件里(在backend>api>login.js里)

login.js 通过$axios向后端发送post方式的请求,请求地址是“/employee/login”,然后把数据“data”带过来,这个数据“data”就是login.html里的loginForm,里面放的就是我们的用户名和密码,这样我们的请求便发出去了;

请求发出去,我们的服务端接收到之后,就需要在我们的服务端进行处理,处理完之后,还需要给我们前端页面一个响应结果;

这个结果我们通过“res”来进行接收;

    ④ res接收到之后,res.code是否等于1,1表示登录成功;

    ⑤ 登录成功之后,将相应的数据转为json,然后把它保存起来;保存在浏览器当中;

    ⑥ 然后做一个页面跳转,跳转到“/backend/index.html”页面上,即主页面;

    ⑦ 当res.code不等于1时(else),即登录失败,就会提示一个错误信息,然后〔this.loading = false〕,登录页面上“登录中”按钮重新变为“登录”按钮,然后重新输入登录名和密码,再点登录按钮就好了;
    ⑧ 这段代码重点关注“res.code”“res.data”“res.msg”,它从这个返回结果里面,获得这些值,这就要求我们服务端处理完之后,数据里边应该还有我们这个code、data、msg等这些数据,这样我们的前端页面才能获取到这些数据;【在明确我们的服务端处理完这些数据之后,应该给我们的页面响应什么样的数据,而且这个数据应该是一个json格式的数据】

code、data、msg等这些数据是我们的后端(服务端)给前端页面响应回来的数据,应该就含有这些信息;

这就是整个的需求分析,一会儿就要根据这个分析来代码实现它;

1.3 代码开发

1.3.1 创建实体类Employee,和employee表进行映射;

(1) 一般规则:数据库中有一个表,便要去创建一个实体类,来跟这个表进行映射,因为后面需要通过MyBatis plus,对数据库进行操作,这个实体类的属性,需要跟我们表里的字段,进行一一对应就可以了;

(2) 在这里可以直接导入资料中提供的实体类(位置:吉瑞外卖项目>资料>实体类>Employee.java);

在IDEA项目中,src>main>java>com.itheima>reggie下新建包entity(实体包),以后所有的实体类都放在这个包下;将实体类Employee.java复制粘贴到entity包里面;

(3) 实体类Employee.java代码分析:

package com.itheima.reggie.entity;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;

@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;

}

      ① 代码分析一:

  • 下面这些是与表格employee中的字段名一一对应的:
    private Long id;

    private String username;

    private String name;

    private String password;

    private String phone;

    private String sex;

      ② 代码分析二:

    private String idNumber;

    private LocalDateTime createTime;

    private LocalDateTime updateTime;
  • idNumber 代表的是身份证号码(驼峰命名法);对应表employee中id_number字段;
  • createTime对应表employee中create_time字段;
  • updateTime对应表employee中update_time字段;
  • 注意:这里实现idNumber和id_number的映射关系,需要在src/main/resources/application.yml中开启驼峰命名;

在这里插入图片描述

1.3.2 在IDEA中,将整个调用链条上的控制层Controller、业务层Service、持久层Mapper创建出来,但需要放到不同的包下面;

(1) 在src>main>java>com.itheima>reggie下,新建包controller、包service、包mapper;

其中包Service又分为接口和实现类,所以在包Service里面再新建实现类包impl;Service接口则直接放在Service包下即可;

在这里插入图片描述
上面这些 Controller、Service、Mapper 基于Mybatis plus创建的,直接根据要求继承BaseMapper或者实现IService接口就可以了;

(2) 在包src>main>java>com.itheima>reggie>mapper下,新建接口 EmployeeMapper.java;

      ① 继承 BaseMapper ,加一个注解@Mapper,再加一个泛型
在这里插入图片描述

(3) 在包src>main>java>com.itheima>reggie>service下,新建接口 EmployeeService.java;

      ① 继承 IService ,再加一个泛型

在这里插入图片描述
      ② 创建接口 EmployeeService.java的实现类EmployeeServiceImpl.java,放到包src>main>java>com.itheima>reggie>service>impl下;

加一个注解 @Service,继承ServiceImpl.java父类,指定泛型EmployeeMapper和Employee,实现接口EmployeeService.java

在这里插入图片描述
(4) 在包src>main>java>com.itheima>reggie>controller下,创建EmployeeController.java,

在这里插入图片描述

      ① 加注解:

  • 加日志注解@Slf4j,能在控制台(F12)输出日志,方便调试;
  • 加注解@RestController
  • 加注解@RequestMapping(“/employee”) —— 加“employee”的目的是在请求路径里面有employee,如下图:

在这里插入图片描述
      ② 在代码里,把我们创建的接口 EmployeeService 注入进来,再加一个注解 @Autowired;

1.3.3 导入通用返回结果类R.java,服务端响应的数据最终都会封装成此对象

(1) 上面这些就是登录功能所需要用到的Controller、Service、Mapper都已经创建好了,接下来就是需要写我们的登录方法了,但在写登录方法之前,还需要导入返回结果类R;

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

      ② R.java,名字叫什么都行,因为后面需要编写很多controller类,controller类里的方法也有很多,这些方法基本上都是响应客户端页面发过来的一些请求,controller处理完之后,要给我们的页面一个结果,而这个结果封装的话,我们在这个项目中是统一的、把所有的返回结果,全都封装成一个R对象,即 R.java:

      ③ R.java 代码展示:

package com.itheima.reggie.common;

import lombok.Data;
import java.util.HashMap;
import java.util.Map;

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

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

    private String msg; //错误信息

    private T data; //数据

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

    public static <T> R<T> success(T object) {
        R<T> r = new R<T>();
        r.data = object;
        r.code = 1;
        return r;
    }

    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;
    }

}

      ④ 在这里这个类已经写好了,直接导入进来使用就可以,在 瑞吉外卖-资料\1 瑞吉外卖项目\资料\服务端返回结果类\R.java中

在IDEA中,包src>main>java>com.itheima>reggie下,新建包common(通用的意思),将R.java直接复制粘贴到包common里面,

(2) R.java代码执行解析:

在这里插入图片描述
在这里插入图片描述

      ① 前面在分析登录页面login.html的时候,可以看到 handleLogin() 是我们前端页面的登录方法(在页面点击登录按钮之后,就会触发这个方法),然后就会通过if(valid)进行校验,校验之后就会通过loginApi进行发送请求,调用login.js里的loginApi()方法,这个loginApi()通过ajax,向我们的后端controller发送请求(‘url’:‘/employee/login’)……

      ② 请求完之后,login.html里的res就是我们后端controller响应回来的结果,然后通过res.code和res.data和res.msg获得响应的值;

      ③ 而我们的R.java对象就是对应的code和data和msg,这样我们的前端页面login.html 才能通过这样的属性,获取响应的值……

      ④ 所以只有我们的服务端R.java给前端响应的就是这种格式的数据,在我们的前端才会拿到这样的数据;

      ⑤ R.java中代码:提供的四个属性解析:

  • private Integer code; 这里code表示编码,以响应码的形式表示返回结果,如果是1时,表示成功,如果是0则表示失败;
  • private String msg; 这里msg指错误信息,比如说登录错误,就会向msg设置值,即登录失败是,就会通过msg这个属性进行封装;
  • private T data; 数据,比如说数据实体,如员工实体employee,放到这里的data属性里面;这样我们前端页面login.html里的data就能转为json,然后存储到我们的浏览器当中……
  • private Map map = new HashMap(); 这里封装的是一些动态数据,使用的地方不是很多,暂时不用管;

      ⑥ R.java中代码:提供的三个方法解析:

在这里插入图片描述

  • success() 方法就是说当我们登录成功的时候,我们就会返回一个R对象;我们其实不用去newR对象,而是直接通过R.success,因为它是一个静态的(static),在这个方法内部就已经new了……

在这里插入图片描述

  • error() 方法就是说当我们登录失败的时候,就会调用这个静态方法(用R.error的方式调用),error() 方法代码可以知道它也是封装成一个R对象……

在这里插入图片描述

  • add() 方法就是用来操作map这个动态数据的,到时候用到再说;

(3) R.java 总结:以后编写的所有的controller,只要这个controller的方法有返回值,那么都会封装成R对象,进行返回,为了增强R.java的通用性,还在上面加了一个泛型,表示我们主体的数据最终就会传进来;

1.3.4 在Controller中创建登录方法(一)梳理登录方法处理逻辑:

(1) 处理逻辑如下:

      ① 将页面提交的密码password进行md5加密处理;

      ② 根据页面提交的用户名username查询数据库;

      ③ 如果没有查询到则返回登录失败结果;

      ④ 密码比对,如果不一致则返回登录失败结果;

      ⑤ 查看员工状态,如果为已禁用状态,则返回员工已禁用结果;

  • “查看员工状态是否已禁用”:类似于锁定账号,在员工表employee里面有一个字段status,值为1时,表示正常使用状态;如果为0,则表示锁定状态;

      ⑥ 登录成功,将员工id存入Session并返回登录成功结果;

在这里插入图片描述

(2) 编写登录方法:在src>main>java>com.itheima>reggie>controller>EmployeeController.java里面:

      ① 返回值是R,注意导入的是R (com.itheima.reggie.com)下的R,泛型对应的是这个对象;方法名叫login(),暂时先返回 return null;

      ② 再加一个注解 @PostMapping ,因为我们前端发送的请求,是一个post方式的请求(Request Method:POST),所以这个地方就是 @PostMapping,这里请求的url路径需要跟(Request URL:http://localhost:8080/employee/login)匹配,所以这里注解应该写成 @PostMapping(“/login”),才能匹配到;

在这里插入图片描述

      ③ 前端点击登录按钮的时候,发送的请求还给我带过来了两个参数(username和password),但需要注意这两个参数是json形式的;所以在EmployeeController.java里面的login() 方法里的参数里面加一个注解 (@RequestBody Employee employee);

在这里插入图片描述
需要注意的是,在这里传的key中,一个k叫username,另一个k叫password,它需要跟(reggie/entity/Employee.java)里的username和password属性命名要一样,否则无法封装成功;

在这里插入图片描述
      ④ 在这里还需要给login()方法再加一个参数(HttpServletRequest request),因为登录成功之后,需要把employee员工对象的ID存到session一份,表示登录成功,这样的话我们想要获取登录用户的话,就会随时获取出来。到时候就可以通过request对象get一个session;所以request一会儿就会用到,在这里提前准备好;
在这里插入图片描述

1.3.5 在Controller中创建登录方法(二) EmployeeController.java
  • 在 src>main>java>com.itheima>reggie>controller>EmployeeController.java中编写代码:

(1) 复制上面提到过的6个逻辑步骤到代码里:

在这里插入图片描述
按照这六步来编写代码;

(2) 代码编写:将页面提交的密码password进行md5加密处理

      ① 页面提交的密码其实已经封装到employee里面了,在这里只需要通过〔String password = employee.getPassword();〕拿到密码就可以;

      ② 拿到密码之后,调用工具类DigestUtils,这里面有md5加密的工具方法md5DigestAsHex();然后将我们的密码传进来,转成getBytes数组的方式,即md5DigestAsHex(password.getBytes());

这样,这串代码〔DigestUtils.md5DigestAsHex(password.getBytes());〕就会对我们明文的密码进行一个处理;

处理完之后,再赋给密码自己,就省的再去创建一个新的变量了,即〔password = DigestUtils.md5DigestAsHex(password.getBytes());〕

      ③ 代码如下图:

在这里插入图片描述
(3) 代码编写:根据页面提交的用户名username查询数据库;

      ① 因为在这里要根据用户名username查询数据库;所以在这里需要new一个LambdaQueryWrapper对象,泛型是(Employee是一个实体类),完整代码写法:〔LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();〕—— 包装一个查询对象;

      ② 接下来需要根据用户名Username,添加查询条件(等值查询):〔queryWrapper.eq(Employee::getUsername.employee.getUsername())〕

解析,传过来的也是在employee对象里面,所以在这里直接用employee.getUsername();
这样条件就封装好了;

      ③ 接下来便可以调用employeeService的getOne()方法,然后把queryWrapper对象传进来;在这里用getOne()方法的原因是我们的数据库里面,已经对Username字段做了唯一的约束(Unique),既然是唯一的,便可以调用getOne()这个方法,去查出来唯一的一个数据,查出来之后,封装成一个Employee对象;

完整代码:〔Employee emp = employeeService.getOne(queryWrapper);〕

      ④ 根据页面提交的用户名username查询数据库代码如下:

在这里插入图片描述

(4) 代码编写:如果没有查询到则返回登录失败结果;

      ① 看一下这个数据到底有没有查到,即使用if语句;判断emp是否等于空(null),如果等于空,则说明没有查到,直接return返回登录失败的结果;而这个登录失败的结果,则需要封装成上面的R对象,所以在这里写成〔return R.error(“登录失败”);〕

      ② 代码如下:

在这里插入图片描述
(5) 代码编写:密码比对,如果不一致则返回登录失败结果;

      ① 数据库查到的密码跟我们明文处理完之后的密码(即将页面提交的password进行md5加密处理后的密码)进行比对;用if判断语句;

      ② 数据库里的密码emp.getPassword()和处理完之后的密码password进行比对equals(),因为在这里比对的是不成立的时候,所以在这里要加一个非!

      ③ 返回一个提示信息 return R.error(“登录失败”);

      ④ 代码如下:

在这里插入图片描述

(6) 代码编写:查看员工状态,如果为已禁用状态,则返回员工已禁用结果;

      ① if判断语句,0表示禁用,1表示可用;

      ② 代码如下:

在这里插入图片描述

(7) 代码编写:登录成功,将员工id存入Session并返回登录成功结果

      ① 怎么获得Session呢?在EmployeeController.java上面有一个request对象,通过这个request来getSession:

在这里插入图片描述

      ② 之后,再返回 return R.success(emp),这个emp对象就是刚才从数据库里面查出来的这个对象;

在这里插入图片描述
      ③ 代码如下:

在这里插入图片描述

1.4 功能测试

1.4.1 Controller中 EmployeeController.java的代码功能测试:
  • 在 src>main>java>com.itheima>reggie>controller>EmployeeController.java中测试代码:

(1) 测试一下上面写的EmployeeController.java代码有没有问题,需要先重新启动一下服务;然后通过加断点的方式调试跟踪一下程序处理有没有问题;

      ① 在 String password = employee.getPassword(); 前面加一个断点,
加断点后,服务已经启动成功的状态:

在这里插入图片描述
      ② 回到页面上,重新输入用户名admin和6位数密码,先输入一个错误的密码,点击登录按钮,就会跳到IDEA中的EmployeeController.java上:

在这里插入图片描述

  • 然后查看数据封装有没有问题,在如下图所画的位置,点击employee下面的提示“+{Employee}”,就会跳到数据封装页面:

在这里插入图片描述
在这里插入图片描述
(2) 继续往下进行单步调试,进行md5加密处理:

在这里插入图片描述

(3) 处理完看看没问题之后,接下来开始查数据库getOne

在这里插入图片描述

      ① 点击emp下面的加号内容:

在这里插入图片描述
就会跳转到下面的页面,条件是用户名必须是正确的:

在这里插入图片描述
      ② 查出来之后,查看第一个if判断瑜伽:if(emp == null),点击下面的符号(如下图),因为不等于空,所以直接跳过去了。

在这里插入图片描述
      ③ 下一步进行密码比对,点击下图画出的那个符号,因为在上面输入的密码是错误的,所以要进到〔R.error(“登录失败”)〕这里,返回错误信息;然后点击“放行”符号,跨过去;

在这里插入图片描述
然后回到页面当中,点击控制台里面的Console选项,会看到一行报错:“Uncaught(in promise) Error:timeout of 1000ms exceeded”(表示已超时),原因是在后端EmployeeController.java代码里加了一个断点,一直在这里卡着,我们一直没有给前端页面响应,而且前端页面设置的超时时间是10s,如果10s不给响应,页面就会抛出上面说的异常;所以为了方便我们调试,要先将这个超时时间设置大一点;

找到前端的js(resources>backend>js>request.js),将timeout默认的1000后面再加两个零;改完之后,记得把服务器重新启动一下;

在这里插入图片描述
重新启动完之后,在EmployeeController.java代码页面上,下方控制台Console选项,右键选择 Clear All;

在这里插入图片描述

然后回到浏览器页面,将登录页面重新刷新一下,点击登录按钮,又会跳转到IDEA中的EmployeeController.java代码页面上;

然后再次点击employee下面显示的〔+{Employee@6423}〕

在这里插入图片描述
就会再次跳转到如下页面:

在这里插入图片描述
这样这一步就算完成了,然后在IDEA中,点击控制台下方的如下图按钮往下走,继续进行断点测试:

在这里插入图片描述
      ④ 测试“查看员工状态”在emp上点击下面显示的〔+Employee@{7112}〕,跳转到下面的页面,查看status=1就正确;

在这里插入图片描述
在这里插入图片描述
      ⑤ 继续点击控制台上的测试按钮往下走,测试“登陆成功,将员工id存入Session并返回登录成功结果”

因为上面的测试都正确,这一步就会直接存入Session里面,返回successs;

      ⑥ 点击IDEA中控制台上的如下图按钮,然后返回到浏览器登录页面:
在这里插入图片描述
注意,如果在登陆页面又看到如下报错,还是超时,是因为浏览器有缓存,在js里面改的时间没有生效;清理一下浏览器的历史记录,重新刷新一下页面就可以了;

在这里插入图片描述

在这里插入图片描述

在浏览器登录页面再次点击登录按钮,跳转到IDEA的EmployeeController.java代码页面上,继续点击控制台上的测试按钮往下走,一直到测试“登陆成功,将员工id存入Session并返回登录成功结果”上,点击IDEA的控制台的放行图标“绿三角”,然后就会跳转到浏览器页面(从登录页面进入员工管理页面)

在这里插入图片描述
在这里插入图片描述
(4) 登陆成功之后,找到登录页面 src>main>resources>backend>page>login>login.html

      ① 员工登录成功之后,调用了login.html里的代码localStorage.setItem然后把我们的数据data转成json,然后写到浏览器userInfo里面(放到浏览器的Application里面);

在这里插入图片描述
在这里插入图片描述

(5) 登录失败返回的是什么呢?

      ① 输入一个不存在的用户名,比如aaaa,然后点击登录按钮,跳转到IDEA的EmployeeController.java代码页面上,直接取消断点(在断点那个红点上再次点击就能取消)然后点击控制台的放行按钮(绿色三角形),就会直接跳转到浏览器登录页面,显示登录失败提示;这个“登录失败”提示是怎么来的呢?

在这里插入图片描述
在这里插入图片描述

      ② 这个“登录失败”提示是怎么来的呢?

  • 用户名错误,密码正确的时候:回到IDEA中的登录页面login.html,可以看到代码code=1时,表示登录成功,那么code=0时表示登录失败,在EmployeeController.java代码上可以看到登录失败返回的是R.error,所以需要再到R.java代码里寻找,可以在R.java代码里找到:r.code=0;的代码;

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 用户名正确,密码不正确的时候:
  • 用户名正确,密码正确,数据库错误的时候(手动将表格employee中的status字段的记录1改为0,表示账号被锁定),回到浏览器再次登录,就会显示“账号已禁用”,测试完之后记得改回来;

在这里插入图片描述

在这里插入图片描述

============================================

2.后台退出功能开发

2.1 概述:从三个方面来入手:需求分析,代码开发,功能测试;

2.2 概述:后台退出功能开发:需求分析

2.2.1 首页面退出按钮

(1) 员工登录成功后,页面跳转到后台系统首页面(backend/index.html),此时会显示当前登录用户的姓名:如果员工需要退出系统,直接点击右侧的退出按钮即可退出系统,退出系统后页面应跳转到登录页面;

在这里插入图片描述
(2) 后台系统首页面右上角的退出按钮(包括管理员+退出图标),先分析一下“管理员”这三个字是怎么显示在页面上的(是固定写死的还是动态展示的):

      ① IDEA中的index.html(src>main>resources>backend>page>login>login.html)

在这里插入图片描述
userInfo的来历:应该从数据模型里面拿,在VUE对象创建的时候,钩子函数created里面,通过localStorage把userInfo取出来,进行if判断,如果userInfo不等于空,则在数据模型里面添加了这么一个userInfo,如下图:

在这里插入图片描述

  • 将userInfo取出来之后,在如下图的地方就可以动态展示了;

在这里插入图片描述

  • 回到浏览器页面,就可以查看我们存储好的userInfo了,F12调出控制面板:

在这里插入图片描述

  • 回到IDEA中src>main>resources>backend>index.html页面,再看退出

在这里插入图片描述

  • 给这个图片加了一个@click单击事件,点击它的时候就会执行一个logout方法,通过logout方法再调用logoutApi方法,这个方法封装在了login.js文件里面了:
    在这里插入图片描述
    在这里插入图片描述
  • 一会儿要做的就是在我们的服务端编写一个controller来接收这个请求;

2.3 后台退出功能开发:代码开发

2.3.1 代码开发逻辑:

用户点击页面中退出按钮,发送请求,请求地址为/employee/logout,请求方式为POST。

我们只需要在Controller中创建对应的处理方法即可,具体的处理逻辑:

      ① 清理Session中的用户id;

      ② 返回结果;

2.3.2 编写后台退出功能代码:

(1) 在src>main>java>com.itheima>reggie>controller>EmployeeController.java中;

  • 因为在上面写了一个login(登录)方法,所以对应的在下面需要写一个退出方法:
  • public 返回值是R,因为不需要返回数据了,方法名叫logout(退出),先返回个null,不让它报错,再加一个@PostMapping,地址和浏览器上logout的地址一致;然后以HttpServletRequest request对象做为参数(和上面login方法的参数一样);
  • 注意:@PostMapping 声明前端发送的请求是post请求;

在这里插入图片描述
(2) 员工退出代码:

在这里插入图片描述
(3) 清理Session中保存的当前登录员工的id,将employee的属性给移除掉,然后返回R.success,代码如下:

在这里插入图片描述

  • 这样员工退出代码就写完了,结合前端页面来看一下:前端页面会发送一个请求,请求到logout()方法,这个方法把session给清理掉,然后返回一个“退出成功”信息;
  • 然后再打开index.html页面(src>main>resources>backend>index.html),logout()方法,判断code是否等于1,就可以通过removeItem移除浏览器中登录的用户信息,然后做一个页面跳转,跳转到登录页面;

在这里插入图片描述

2.4 后台退出功能开发:功能测试

2.4.1 功能测试

(1) 在IDEA中,EmployeeController.java中重启一下服务器,测试一下退出功能:

      ① 启动成功之后,右键Clear All清理一下控制台:
在这里插入图片描述

      ② 到浏览器页面(localhost:8080/backend/index.html)刷新一下,点击右上角退出按钮之后,跳转到如下页面,说明测试成功:
在这里插入图片描述

============================================

3.分析后台系统首页构成和效果展示方式:

3.1 系统首页面功能分析

3.1.1 系统首页面localhost:8080/backend/index.html

(1) 页面整体分析:当我们登录成功之后,跳转到了系统首页面(localhost:8080/backend/index.html),这个页面分为两部分:左侧为菜单数据,右侧为某个页面的功能列表;

点击左侧菜单时,右侧页面会跟着切换;

(2) 分两个方面分析系统首页面:

      ① 左侧菜单栏是怎么展示出来的?

  • 在index.html页面(src>main>resources>backend>index.html),vue中,menuList里:

在这里插入图片描述

在这里插入图片描述

  • v-for遍历menuList,判断当前item里面有没有children这个属性,以及这个属性的length是否大于0,因为在menuList里面id都大于0,所以这个if不会成立,会直接执行下面的else,所以这里的if先不用去管;

在这里插入图片描述

  • 在v-else中,会将item-name展示出来:

在这里插入图片描述
      ② 为什么点击菜单时右侧会跟着变?

  • 在src>main>resources>backend>index.html中,所有的菜单都加了一个@click单击事件,点击@click事件是,会执行menuHandle()方法:

在这里插入图片描述

  • 在src>main>resources>backend>index.html中,menuHandle()方法:iframeUrl=item.url中的url对应下面如图划红线的url,这里通过iframe的方式显示了一个新的页面,<iframe></iframe>定义的是在右侧页面处展示出一个新的页面;

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 点击菜单时,就会切换到相对应的页面;

四、员工管理业务开发

1.分析“员工管理业务开发”需要完成的功能开发:

  • 完善登录功能
  • 新增员工
  • 员工信息分页查询
  • 启用/禁用员工账号
  • 编辑员工信息

============================================

2.完善登录功能开发

2.1 完善登录功能开发分为三步:问题分析、代码实现、功能测试;

2.2 完善登录功能——问题分析;

(1) 前面我们已经完成了后台系统登录功能开发,但是还存在一个问题:用户如果不登录,直接访问系统首页面,照样可以正常访问。

(2) 这种设计并不合理,我们希望看到的效果应该是,只有登录成功后才可以访问系统中的页面,如果没有登录则跳转到登录页面。

(3) 那么,具体应该怎么实现呢?

  • 答案就是使用过滤器或者拦截器,在过滤器或者拦截器中判断用户是否已经完成登录,如果没有登录则跳转到登录页面。

2.3 代码实现步骤:

(1) 创建自定义过滤器 LoginCheckFilter;

(2) 在启动类上加注解@ServletComponentScan(解析:加入这个注解之后,过滤器LoginCheckFilter才会生效,开启组件扫描,才会扫描我们的过滤器)

(3) 完善过滤器的处理逻辑

        ① 过滤器的具体处理逻辑如下:

  • 获取本次请求的URL;
  • 判断本次请求是否需要处理;
  • 如果不需要处理,则直接放行;
  • 判断登录状态,如果已登录,则直接放行;
  • 如果未登录则返回未登录结果;

在这里插入图片描述

2.4 创建过滤器LoginCheckFilter:

(1) 在IDEA中,src>main>java>com.itheima>reggie下,新建包filter,在包filter下,新建类LoginCheckFilter.java。(LoginCheckFilter.java类的作用是检查用户是否已经完成登录,属于自定义过滤器)

(2) 在LoginCheckFilter.java里,加一个注解〔@WebFilter(filterName=“loginCheckFilter”,urlPatterns=“/*”)〕

  • 解析:filterName是指定过滤器的名称;urlPatterns是指拦截哪些请求路径;“/*”指所有请求路径;

(3) 在LoginCheckFilter.java里,过滤器LoginCheckFilter还需要实现一个过滤器接口Filter,并实现接口里的方法:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(4) 在LoginCheckFilter.java里,再加入一个注解@Slf4j //通过日志的方式来输出;

在这里插入图片描述
(5) 在启动类ReggieApplication.java(src>main>java>com.itheima>reggie>ReggieApplication.java)上加一个注解@ServletComponentScan,这样才会去扫描过滤器里的@WebFilter注解,从而扫描到我们创建的过滤器;

(6) 启动一下项目,看看过滤器能不能生效;

在这里插入图片描述

  • 刷新一下浏览器页面:

在这里插入图片描述

  • 再回到IDEA中,看到控制台有 “拦截到请求” 的字样,说明编写成功;

在这里插入图片描述
♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡

2.5 完善登录功能:过滤器LoginCheckFilter代码开发:

(1) 在过滤器(src>main>java>com.itheima>reggie>filter>LoginCheckFilter.java)中,复制上面的五个步骤到代码中,然后根据这五个步骤一一实现代码编写;

在这里插入图片描述
(2) 获取本次请求的URI:

      ① 在过滤器LoginCheckFilter.java中,因为已经得到了request对象,所以在这里直接通过request.getRequestURI()来获得本次请求的URI;

在这里插入图片描述
(3) 判断本次请求是否需要处理(检查用户是否已经完成登录了):

      ① 在过滤器LoginCheckFilter.java中,并不是所有的请求都需要处理,有些请求路径不需要处理,直接放行,所以定义不需要处理的请求路径;

在这里插入图片描述
      ② 在过滤器LoginCheckFilter.java中,如果获取本次请求的路径是〔/backend/index.html——系统首页面〕,但是这个写法跟“/backend/**”写法是不一致的,那么如何去匹配呢?这时就需要在上面添加一个新的对象AntPathMatcher,这个对象就是专门用来进行路径比较的;

在这里插入图片描述
      ③ 下面该判断本次请求是否需要处理,在这里就是判断请求的“/backend/index.html”是否是在“定义的不需要处理的请求路径”里面,如果是,则不需要处理;

  • 在这里的判断可以直接封装一个方法check()来判断,返回值为boolean布尔类型,然后把我们请求的路径requestURI传到参数中;
  • 然后把上面定义的不需要处理的路径 urls传进方法check()里进行遍历,看看里面的某一项是否跟我们这次请求的“/backend/index.html”匹配,若能匹配,则需要放行;
  • 在方法check()参数中还需要传进来一个数组“String[] urls”;
  • 在方法check()遍历urls(在IDEA中for的快捷写法urls.for+回车),遍历出来之后便可以使用我们上面定义的路径匹配器PATH_MATCHER;跟着的match(String pattern,String path) 就是匹配的意思,()中的第一个参数就是我们从遍历出来的一个个的url元素,第二个参数就是我们传过来的requestURI;
  • 开始判断,如果返回true(即match=true)时,说明已经匹配上了,就没有必要再循环,直接返回true;如果未匹配,则返回false;
  • 代码如下:

在这里插入图片描述

      ④ 在过滤器LoginCheckFilter.java中,上步方法写好之后,在上面只需要调用这个check()方法即可,代码如下:
在这里插入图片描述
然后通过check的返回值,就能判定我们请求的这个路径是否包含在urls当中;

(4) 如果不需要处理,则直接放行(即check=true的时候,则直接放行),代码如下:

在这里插入图片描述
(5) 判断登录状态,如果已登录,则直接放行

  • 如果上面那一步的if不成立,就说明这次的请求需要处理,需要判断用户是否已经完成登录,如何判断?就需要从session里面获取登录用户,如果能获取出来,则直接放行。

在这里插入图片描述
(6) 如果未登录则返回未登录结果,通过输出流的方式向客户端响应数据;

      ① 如果上一步没有放行,说明没有登录,在这里不是直接跳页面,需要结合js来看,

  • 在所有index.html中,都会引入一个request.js文件:

在这里插入图片描述
在这里插入图片描述

  • 通过response对象,在调用write()方法,把R对象转成JSON,然后通过输出流write将它写回去,最后直接ruturn就可以。
  • 注意:与request.js里面响应拦截器中的NOTLOGIN相对应;

在这里插入图片描述
(7) 这样过滤器LoginCheckFilter.java代码就已经编写完成,可以进行测试了;

♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡♡

2.6 完善登录功能:过滤器LoginCheckFilter代码测试:

(1) 在测试代码之前,先在代码LoginCheckFilter.java中加一些日志,方便调试

  • 第一处:

在这里插入图片描述

  • 第二处:

在这里插入图片描述

  • 第三处:

在这里插入图片描述

  • 第四处:

在这里插入图片描述

(2) 重新启动一下IDEA,然后在浏览器中,直接输入http://localhost:8080/backend/index.html+回车,就会发现,网页还会自动跳回登录页面,点击“登录”按钮登录后,才能正常跳转;
然后再回到IDEA中,查看控制面板,就会发现“拦截到请求”字样,如下图:

在这里插入图片描述
(3) 在这里登录页面跳转,是由backend>js>request.js里面的〔window.top.location.href = ‘/backend/page/login/login.html’〕;
      ① 在浏览器中调试这个js代码:在浏览器登录页面,按F12→Sources→在request.js拦截器这个地方加断点:
在这里插入图片描述
      ② 然后在浏览器中输入网址http://localhost:8080/backend/index.html+回车,查看控制面板:

在这里插入图片描述
在这里插入图片描述


3.新增员工

3.1 新增员工通过四个方面来完成:需求分析、数据模型、代码开发和功能测试;

3.2 新增员工- 需求分析:

(1) 后台系统中可以管理员工信息,通过新增员工来添加后台系统用户。点击[添加员工]按钮跳转到新增页面,如下:
在这里插入图片描述
在这里插入图片描述

3.3 新增员工 - 数据模型:

(1) 新增员工,其实就是将我们新增页面录入的员工数据插入到employee表。需要注意,employee表中对username字段加入了唯一约束,因为username是员工的登录账号,必须是唯一的。

在这里插入图片描述
(2) employee表中的status字段已经设置了默认值1,表示状态正常:

在这里插入图片描述

  • status 代表当前用户/员工账号的状态—— 0(禁用) / 1(正常);默认值是1;
  • 新增员工,其实就是向表employee里插入数据;

3.4 新增员工 - 代码开发(梳理程序执行流程):

(1) 在代码开发之前,需要梳理一下整个程序的执行过程:

  • 页面发送ajax请求,将新增员工页面中输入的数据以json的形式提交到服务端;
  • 服务端Controller接收页面提交的数据并调用Service将数据进行保存;
  • Service调用Mapper 操作数据库,保存数据;

在这里插入图片描述

(2) 在浏览器中,“添加员工”页面里输入员工信息,点击【保存】按钮,按F12打开控制面板→Network:
在这里插入图片描述
(3) “添加员工”的代码位置:src>main>resources>backend>page>member>list.html

在这里插入图片描述

3.5 新增员工 - 代码开发(代码编写):

(1) 实现代码步骤:因为前端页面上请求已经发出来了,现在要做的就是在Controller里创建一个方法,把我们的页面发送的请求数据给接收到;

(2) 在IDEA中,src>main>java>com.itheima>reggie>controller>EmployeeController.java里编写代码:

在这里插入图片描述
解析:因为传过来的是json形式的,所以需要在方法save里面加一个注解@RequestBody

(3) 测试一下上面刚刚编写的代码:

  • 在IDEA的EmployeeController.java中 log.info() 处加断点跟踪一下,要保证前端页面发送的请求能够请求到save方法,并且我们提交的参数能够封装到employee对象上;
  • 然后回到浏览器首页面(http://localhost:8080/backend/page/login.html)→ 点击“登录” → 登陆成功之后,点击左上角“添加员工” → 输入员工的信息(身份证号要输入18位的数字),并点击“保存”
  • 再回到 IDEA的EmployeeController.java中,就看到刚才输入的信息已经封装过来了,然后点击下图所示employee处显示的加号,跳转到参数页查看输入的信息有没有问题;
    在这里插入图片描述
    在这里插入图片描述
    (4) 由显示的信息可以看到,密码password为空,是因为在“添加员工”时没有密码的输入框,如下图:
    在这里插入图片描述
  • 所以在这里新增员工的时候,都统一给个初始密码(123456),后期员工自己登录进来的时候可以自己修改密码;所以在 IDEA的 EmployeeController.java 中,“新增员工”处,设置初始密码:在employee对象的基础之上,设置密码 setPassword();
  • 注意:在这里设置密码不要设置明文的,要用md5进行加密;
  • 所以代码写法如下:

设置初始密码

(5) 在IDEA的EmployeeController.java中,“新增员工”里手动设置其余空的属性:

      ① 再回到 Employee.java里面,会看到 createTime(创建时间),updateTime(更新时间),createUser(创建人),updateUser(更新人)等还都是空的,其中status在创建表的时候就默认给了1,所以在这里不用再设置;

      ② 创建人/当前登录用户的ID,在这里我们登录成功之后,已经把用户的ID放到session里面了,所以在save()方法的参数里面添加一个〔HttpServletRequset request〕对象来得到一个session;

      ③ 代码如下:

在这里插入图片描述
“获得当前登录用户的id”代码解析:

  • 通过request.getSession().getAttribute(“employee”)
  • 获得的时候是按照上面“登陆成功……”里面的setAttribute里面的k(即employee)来获得;

在这里插入图片描述

  • 因为“登陆成功……”放进去的时候,用的是emp.getId(),所以现在取出来也是用getId;
  • 因为方法getAttribute()方法返回的都是object类型,所以在这里需要添加强转,转成Long类型;

在这里插入图片描述

  • 调用employeeService.save()方法,将employee对象传进去,最后返回成功信息:return R.success(“新增员工成功”);
  • 其中employeeService调用的这个save()方法是继承了Mybatis-plus里的父接口IService里面的save()方法,在这里是直接调用的;

3.6 新增员工 - 代码测试:

(1) 现在新增员工的代码就已经写完了,启动一下项目,测试一下程序有没有问题;
在这里插入图片描述
(2) 回到浏览器页面(http://localhost:8080/backend/page/login/login.html),登录后添加员工,输入员工信息后点击保存;
在这里插入图片描述
(3) 再到IDEA中,看到控制台发了条Insert语句;
在这里插入图片描述

(4) 再到数据库中找到 employee表刷新一下,就能看到新加的员工数据;
在这里插入图片描述

3.7 新增员工 - 编写全局异常处理器

(1) 问题:现在再输入一条“账号”相同,其他内容不同的员工数据时,点击“保存”后就会显示“系统接口500异常”,因为在表格employee中的username(账号)字段加了唯一约束,不能够重复;
在这里插入图片描述

  • 回到IDEA中,在控制台就会看到如下图的异常,说的是出现了重复的值

在这里插入图片描述
(2) 上面的操作出现的问题及处理方式分析:
      ① 前面编写的“新增员工”程序还存在一个问题,就是当我们在新增员工输入的账号已经存在时,由于employee表中对该字段加入了唯一约束,此时程序会抛出异常;

      ② 此时需要我们的程序进行异常捕获,通常有两种处理方式;

  • 方式一:在Controller方法中加入try、catch进行异常捕获;(不建议使用)
  • 方式二:使用异常处理器进行全局异常捕获;(建议使用)
try{
	employeeService.save(employee);
}catch(Exception ex){
	R.error("新增员工失败");
}

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

(3) 编写全局异常处理器(GlobalExceptionHandler.java)

      ① 在 src>main>java>com.itheima>reggie>common里面新建一个全局的异常捕获类 GlobalExceptionHandler.java(即:全局异常处理器),这个类的底层是基于代理我们编写的 Controller,所以这个全局异常处理器会通过AOP(面向切面编程)把我们的save()方法等拦截到,如果抛异常,就都会在类GlobalExceptionHandler.java中的某个方法里进行处理;

      ② 在类GlobalExceptionHandler.java,加入注解:
在这里插入图片描述
      ③ 创建方法 exceptionHandler(),返回R对象,泛型是,加的注解是@ExceptionHandler() → 括号里面写要处理的异常;一旦Controller抛SQLIntegrityConstraintViolationException异常,就会被类GlobalExceptionHandler.java拦截到,统一在方法exceptionHandler()这里处理
在这里插入图片描述
在这里插入图片描述


总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 瑞吉外卖是一个基于Java开发项目实战,适用于在线外卖订餐系统。该项目提供了用户注册、登录、浏览餐厅、查看菜单、下订单等功能。 首先,我们需要在网盘上下载瑞吉外卖项目源代码文件。通过提供的下载链接,我们可以将项目源代码文件下载到本地。下载完成后,我们可以将文件解压缩,并使用Java开发工具(如Eclipse或IntelliJ IDEA)导入项目。 接下来,我们需要安装项目所需的Java开发环境。确保已经安装了JDK(Java Development Kit)和Maven(项目构建工具)。这样可以保证项目能够正常编译和运行。 在导入项目后,我们可以查看项目的目录结构。主要包括源代码、配置文件和静态资源文件等。在源代码文件夹中,我们可以找到各种Java类文件,包括控制器、实体类、服务类等。配置文件夹中包含项目的配置文件,用于配置数据库连接、日志记录等。静态资源文件夹中包含了项目所需的各种图片、样式表和JavaScript文件等。 在开始开发之前,我们需要先配置数据库。将提供的SQL脚本文件导入到MySQL数据库中,并在项目配置文件中修改数据库连接相关的配置信息。 接下来,我们可以根据需求对项目进行开发和定制化。例如,我们可以根据需要添加更多的功能模块,如优惠券管理、配送员管理等。我们也可以根据需求修改前端页面的样式和布局,以满足用户的需求。 开发完成后,我们可以使用Maven将项目打包成可执行的WAR文件。将WAR文件上传至服务器,并部署在Tomcat等Java Web服务器上。通过访问服务器的IP地址和端口号,我们就可以在浏览器中访问瑞吉外卖系统了。 总之,下载并实战瑞吉外卖项目需要下载源代码文件,并在Java开发工具中导入项目。然后,我们可以根据需求进行开发和定制化,并最终将项目打包部署在服务器上。最后,我们可以通过浏览器访问项目,体验瑞吉外卖系统的功能。 ### 回答2: 瑞吉外卖是一个基于Java语言开发项目实战,项目的主要目标是实现一个在线外卖订餐系统。用户可以通过网页或手机应用程序浏览餐厅菜单、下订单、查看订单状态等功能。 该项目开发环境主要包括Java SE、Java EE、Spring框架和MySQL数据库。其中,Java SE用于实现基本的语言特性和数据处理操作,Java EE用于构建Web应用程序,Spring框架用于实现系统的MVC架构,MySQL数据库用于存储用户信息、菜品信息和订单数据等。 项目的实施步骤如下: 1. 需求分析:首先,根据用户的需求分析,确定项目的基本功能和需求。 2. 系统设计:基于需求分析的结果,进行系统设计,包括数据库设计、界面设计和系统架构设计等。 3. 环境搭建:安装配置Java开发环境,包括JDK、开发工具(如Eclipse或IntelliJ IDEA)、Web服务器(如Tomcat)和数据库管理系统(MySQL)。 4. 数据库建模:创建数据库表结构,定义各个表之间的关系。 5. 编码实现:根据系统设计的结果,进行编码实现,包括前端界面的开发和后端功能的开发。 6. 软件测试:对已实现的功能进行测试,包括单元测试、集成测试和系统测试等,保证系统的稳定性和可靠性。 7. 部署上线:将项目部署到服务器上,使用户可以通过网络访问系统。 8. 运维和优化:监控系统运行情况,对性能进行优化和改进。 最后,用户可以通过网盘下载瑞吉外卖的源代码和相关文档,以便学习和参考。项目实战瑞吉外卖开发过程将帮助开发者熟悉Java开发技术,并理解实际项目的需求分析、系统设计和开发实施等流程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值