【瑞吉外卖】day03:完善登录功能与新增员工(一)

简介: 完善登录功能与新增员工

1. 完善登录功能


1.1 问题分析


前面我们已经完成了后台系统的员工登录功能开发,但是目前还存在一个问题,接下来我们来说明一个这个问题, 以及如何处理。

1). 目前现状

用户如果不登录,直接访问系统首页面,照样可以正常访问。

image.png

2). 理想效果

上述这种设计并不合理,我们希望看到的效果应该 是,只有登录成功后才可以访问系统中的页面,如果没有登录, 访问系统中的任何界面都直接跳转到登录页面。

image.png

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

可以使用我们之前讲解过的 过滤器、拦截器来实现,在过滤器、拦截器中拦截前端发起的请求,判断用户是否已经完成登录,如果没有登录则返回提示信息,跳转到登录页面。

1.2 思路分析


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

image.png

A. 获取本次请求的URI

B. 判断本次请求, 是否需要登录, 才可以访问

C. 如果不需要,则直接放行

D. 判断登录状态,如果已登录,则直接放行

E. 如果未登录, 则返回未登录结果

如果未登录,我们需要给前端返回什么样的结果呢? 这个时候, 我们可以去看看前端是如何处理的 ?

image.png

1.3 代码实现


1). 定义登录校验过滤器

自定义一个过滤器 LoginCheckFilter 并实现 Filter 接口, 在doFilter方法中完成校验的逻辑。 那么接下来, 我们就根据上述分析的步骤, 来完成具体的功能代码实现:

所属包: com.itheima.reggie.filter

<span style="background-color:#f8f8f8"><span style="color:#333333"><span style="color:#770088">import</span> <span style="color:#000000">com</span>.<span style="color:#000000">alibaba</span>.<span style="color:#000000">fastjson</span>.<span style="color:#000000">JSON</span>;
<span style="color:#770088">import</span> <span style="color:#000000">com</span>.<span style="color:#000000">itheima</span>.<span style="color:#000000">reggie</span>.<span style="color:#000000">common</span>.<span style="color:#000000">R</span>;
<span style="color:#770088">import</span> <span style="color:#000000">lombok</span>.<span style="color:#000000">extern</span>.<span style="color:#000000">slf4j</span>.<span style="color:#000000">Slf4j</span>;
<span style="color:#770088">import</span> <span style="color:#000000">org</span>.<span style="color:#000000">springframework</span>.<span style="color:#000000">util</span>.<span style="color:#000000">AntPathMatcher</span>;
<span style="color:#770088">import</span> <span style="color:#000000">javax</span>.<span style="color:#000000">servlet</span>.<span style="color:#981a1a">*</span>;
<span style="color:#770088">import</span> <span style="color:#000000">javax</span>.<span style="color:#000000">servlet</span>.<span style="color:#000000">annotation</span>.<span style="color:#000000">WebFilter</span>;
<span style="color:#770088">import</span> <span style="color:#000000">javax</span>.<span style="color:#000000">servlet</span>.<span style="color:#000000">http</span>.<span style="color:#000000">HttpServletRequest</span>;
<span style="color:#770088">import</span> <span style="color:#000000">javax</span>.<span style="color:#000000">servlet</span>.<span style="color:#000000">http</span>.<span style="color:#000000">HttpServletResponse</span>;
<span style="color:#770088">import</span> <span style="color:#000000">java</span>.<span style="color:#000000">io</span>.<span style="color:#000000">IOException</span>;
<span style="color:#aa5500">/**</span>
 <span style="color:#aa5500">* 检查用户是否已经完成登录</span>
 <span style="color:#aa5500">*/</span>
<span style="color:#555555">@WebFilter</span>(<span style="color:#000000">filterName</span> <span style="color:#981a1a">=</span> <span style="color:#aa1111">"loginCheckFilter"</span>,<span style="color:#000000">urlPatterns</span> <span style="color:#981a1a">=</span> <span style="color:#aa1111">"/*"</span>)
<span style="color:#555555">@Slf4j</span>
<span style="color:#770088">public</span> <span style="color:#770088">class</span> <span style="color:#0000ff">LoginCheckFilter</span> <span style="color:#770088">implements</span> <span style="color:#000000">Filter</span>{
    <span style="color:#aa5500">//路径匹配器,支持通配符</span>
    <span style="color:#770088">public</span> <span style="color:#770088">static</span> <span style="color:#770088">final</span> <span style="color:#000000">AntPathMatcher</span> <span style="color:#000000">PATH_MATCHER</span> <span style="color:#981a1a">=</span> <span style="color:#770088">new</span> <span style="color:#000000">AntPathMatcher</span>();
    <span style="color:#555555">@Override</span>
    <span style="color:#770088">public</span> <span style="color:#008855">void</span> <span style="color:#000000">doFilter</span>(<span style="color:#000000">ServletRequest</span> <span style="color:#000000">servletRequest</span>, <span style="color:#000000">ServletResponse</span> <span style="color:#000000">servletResponse</span>, <span style="color:#000000">FilterChain</span> <span style="color:#000000">filterChain</span>) <span style="color:#770088">throws</span> <span style="color:#000000">IOException</span>, <span style="color:#000000">ServletException</span> {
        <span style="color:#000000">HttpServletRequest</span> <span style="color:#000000">request</span> <span style="color:#981a1a">=</span> (<span style="color:#000000">HttpServletRequest</span>) <span style="color:#000000">servletRequest</span>;
        <span style="color:#000000">HttpServletResponse</span> <span style="color:#000000">response</span> <span style="color:#981a1a">=</span> (<span style="color:#000000">HttpServletResponse</span>) <span style="color:#000000">servletResponse</span>;
        <span style="color:#aa5500">//1、获取本次请求的URI</span>
        <span style="color:#008855">String</span> <span style="color:#000000">requestURI</span> <span style="color:#981a1a">=</span> <span style="color:#000000">request</span>.<span style="color:#000000">getRequestURI</span>();<span style="color:#aa5500">// /backend/index.html</span>
        <span style="color:#000000">log</span>.<span style="color:#000000">info</span>(<span style="color:#aa1111">"拦截到请求:{}"</span>,<span style="color:#000000">requestURI</span>);
        <span style="color:#aa5500">//定义不需要处理的请求路径</span>
        <span style="color:#008855">String</span>[] <span style="color:#000000">urls</span> <span style="color:#981a1a">=</span> <span style="color:#770088">new</span> <span style="color:#008855">String</span>[]{
                <span style="color:#aa1111">"/employee/login"</span>,
                <span style="color:#aa1111">"/employee/logout"</span>,
                <span style="color:#aa1111">"/backend/**"</span>,
                <span style="color:#aa1111">"/front/**"</span>
        };
        <span style="color:#aa5500">//2、判断本次请求是否需要处理</span>
        <span style="color:#008855">boolean</span> <span style="color:#000000">check</span> <span style="color:#981a1a">=</span> <span style="color:#000000">check</span>(<span style="color:#000000">urls</span>, <span style="color:#000000">requestURI</span>);
        <span style="color:#aa5500">//3、如果不需要处理,则直接放行</span>
        <span style="color:#770088">if</span>(<span style="color:#000000">check</span>){
            <span style="color:#000000">log</span>.<span style="color:#000000">info</span>(<span style="color:#aa1111">"本次请求{}不需要处理"</span>,<span style="color:#000000">requestURI</span>);
            <span style="color:#000000">filterChain</span>.<span style="color:#000000">doFilter</span>(<span style="color:#000000">request</span>,<span style="color:#000000">response</span>);
            <span style="color:#770088">return</span>;
        }
        <span style="color:#aa5500">//4、判断登录状态,如果已登录,则直接放行</span>
        <span style="color:#770088">if</span>(<span style="color:#000000">request</span>.<span style="color:#000000">getSession</span>().<span style="color:#000000">getAttribute</span>(<span style="color:#aa1111">"employee"</span>) <span style="color:#981a1a">!=</span> <span style="color:#221199">null</span>){
            <span style="color:#000000">log</span>.<span style="color:#000000">info</span>(<span style="color:#aa1111">"用户已登录,用户id为:{}"</span>,<span style="color:#000000">request</span>.<span style="color:#000000">getSession</span>().<span style="color:#000000">getAttribute</span>(<span style="color:#aa1111">"employee"</span>));
            <span style="color:#000000">filterChain</span>.<span style="color:#000000">doFilter</span>(<span style="color:#000000">request</span>,<span style="color:#000000">response</span>);
            <span style="color:#770088">return</span>;
        }
        <span style="color:#000000">log</span>.<span style="color:#000000">info</span>(<span style="color:#aa1111">"用户未登录"</span>);
        <span style="color:#aa5500">//5、如果未登录则返回未登录结果,通过输出流方式向客户端页面响应数据</span>
        <span style="color:#000000">response</span>.<span style="color:#000000">getWriter</span>().<span style="color:#000000">write</span>(<span style="color:#000000">JSON</span>.<span style="color:#000000">toJSONString</span>(<span style="color:#000000">R</span>.<span style="color:#000000">error</span>(<span style="color:#aa1111">"NOTLOGIN"</span>)));
        <span style="color:#770088">return</span>;
    }
    <span style="color:#aa5500">/**</span>
     <span style="color:#aa5500">* 路径匹配,检查本次请求是否需要放行</span>
     <span style="color:#aa5500">* @param urls</span>
     <span style="color:#aa5500">* @param requestURI</span>
     <span style="color:#aa5500">* @return</span>
     <span style="color:#aa5500">*/</span>
    <span style="color:#770088">public</span> <span style="color:#008855">boolean</span> <span style="color:#000000">check</span>(<span style="color:#008855">String</span>[] <span style="color:#000000">urls</span>,<span style="color:#008855">String</span> <span style="color:#000000">requestURI</span>){
        <span style="color:#770088">for</span> (<span style="color:#008855">String</span> <span style="color:#000000">url</span> : <span style="color:#000000">urls</span>) {
            <span style="color:#008855">boolean</span> <span style="color:#000000">match</span> <span style="color:#981a1a">=</span> <span style="color:#000000">PATH_MATCHER</span>.<span style="color:#000000">match</span>(<span style="color:#000000">url</span>, <span style="color:#000000">requestURI</span>);
            <span style="color:#770088">if</span>(<span style="color:#000000">match</span>){
                <span style="color:#770088">return</span> <span style="color:#221199">true</span>;
            }
        }
        <span style="color:#770088">return</span> <span style="color:#221199">false</span>;
    }
}</span></span>

image.png

2). 开启组件扫描

需要在引导类上, 加上Servlet组件扫描的注解, 来扫描过滤器配置的@WebFilter注解, 扫描上之后, 过滤器在运行时就生效了。

<span style="background-color:#f8f8f8"><span style="color:#333333"><span style="color:#555555">@Slf4j</span>
<span style="color:#555555">@SpringBootApplication</span>
<span style="color:#555555">@ServletComponentScan</span>
<span style="color:#770088">public</span> <span style="color:#770088">class</span> <span style="color:#0000ff">ReggieApplication</span> {
    <span style="color:#770088">public</span> <span style="color:#770088">static</span> <span style="color:#008855">void</span> <span style="color:#000000">main</span>(<span style="color:#008855">String</span>[] <span style="color:#000000">args</span>) {
        <span style="color:#000000">SpringApplication</span>.<span style="color:#000000">run</span>(<span style="color:#000000">ReggieApplication</span>.<span style="color:#770088">class</span>,<span style="color:#000000">args</span>);
        <span style="color:#000000">log</span>.<span style="color:#000000">info</span>(<span style="color:#aa1111">"项目启动成功..."</span>);
    }
}</span></span>

image.png

1.4 功能测试


代码编写完毕之后,我们需要将工程重启一下,然后在浏览器地址栏直接输入系统管理后台首页,然后看看是否可以跳转到登录页面即可。我们也可以通过debug的形式来跟踪一下代码执行的过程。

image.png

对于前端的代码, 也可以进行debug调试。

F12打开浏览器的调试工具, 找到我们前面提到的request.js, 在request.js的响应拦截器位置打上断点。

image.png

2. 新增员工


2.1 需求分析


后台系统中可以管理员工信息,通过新增员工来添加后台系统用户。点击[添加员工]按钮跳转到新增页面,如下:

image.png

当填写完表单信息, 点击"保存"按钮后, 会提交该表单的数据到服务端, 在服务端中需要接受数据, 然后将数据保存至数据库中。

2.2 数据模型


新增员工,其实就是将我们新增页面录入的员工数据插入到employee表。employee表中的status字段已经设置了默认值1,表示状态正常。

image.png

需要注意,employee表中对username字段加入了唯一约束,因为username是员工的登录账号,必须是唯一的

image.png

2.3 程序执行流程


在开发代码之前,我们需要结合着前端页面发起的请求, 梳理一下整个程序的执行过程:

image.png

A. 点击"保存"按钮, 页面发送ajax请求,将新增员工页面中输入的数据以json的形式提交到服务端, 请求方式POST, 请求路径 /employee

B. 服务端Controller接收页面提交的数据并调用Service将数据进行保存

C. Service调用Mapper操作数据库,保存数据

相关文章
|
4天前
|
存储 监控 数据挖掘
用CRM系统开启订单-回款自动化管理之旅
在现代企业管理中,CRM系统不仅是客户信息的存储库,更是提升运营效率的关键工具。通过订单到回款的自动化管理,CRM系统减少人为错误、提高响应速度、优化现金流。具体方法包括:订单管理自动化、回款跟踪自动化、财务与CRM集成、数据分析与报告,从而显著提升客户满意度和企业内部效率。CRM系统正成为推动企业持续发展的重要力量。
|
6月前
|
安全 数据安全/隐私保护
会员系统04--移动全栈,移动全栈包含我的,咨讯,行情,钱包四个界面
会员系统04--移动全栈,移动全栈包含我的,咨讯,行情,钱包四个界面
|
6月前
|
前端开发
会员系统02--,后台管理系统,包含网站运营,统计分析,用户中心,财务管理,资金明细,系统管理,参数配置,后台管理系统可以观看配置资料,广告位的相关资料,客服工单最主要是客户反馈给我们的问题,登录统计
会员系统02--,后台管理系统,包含网站运营,统计分析,用户中心,财务管理,资金明细,系统管理,参数配置,后台管理系统可以观看配置资料,广告位的相关资料,客服工单最主要是客户反馈给我们的问题,登录统计
|
8月前
|
存储 JavaScript Java
在线拍卖系统|基于Springboot的在线拍卖系统设计与实现(源码+数据库+文档)
在线拍卖系统|基于Springboot的在线拍卖系统设计与实现(源码+数据库+文档)
197 0
|
8月前
|
安全 JavaScript Java
租房招聘|在线租房和招聘平台|基于Springboot的在线租房和招聘平台设计与实现(源码+数据库+文档)
租房招聘|在线租房和招聘平台|基于Springboot的在线租房和招聘平台设计与实现(源码+数据库+文档)
45 0
|
存储 前端开发 Java
【开题报告】基于 Spring Boot 的在线预约导游系统的设计与实现
【开题报告】基于 Spring Boot 的在线预约导游系统的设计与实现
158 0
|
前端开发 JavaScript API
TienChin 渠道管理-前端展示渠道信息
TienChin 渠道管理-前端展示渠道信息
62 0
TienChin 渠道管理-前端展示渠道信息
|
JSON 前端开发 NoSQL
淘东电商项目(27) -门户登出功能
淘东电商项目(27) -门户登出功能
52 0
|
区块链
OPensea /nft交易平台分红项目系统开发项目方案/功能说明/方案逻辑/源码详情
简单来说,DAPP和普通的App原理一样,除了他们是完全去中心化的,由类似以太坊网络本身自己的节点来运作的DAPP,不依赖于任何中心化的服务器,DAPP是去中心化的,可以完全自动地运行。