【瑞吉外卖】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操作数据库,保存数据

相关文章
|
1月前
|
小程序 JavaScript Java
鲜花销售|鲜花销售小程序|基于微信小程序的鲜花销售系统设计与实现(源码+数据库+文档)
鲜花销售|鲜花销售小程序|基于微信小程序的鲜花销售系统设计与实现(源码+数据库+文档)
21 0
|
1月前
|
新零售 人工智能 大数据
东郊到家预约服务系统开发|现成案例|模式详情
由于线下门店的商品陈列和消费者行为发生在物理空间里,线下门店想收集数据似乎没那么容易
|
1月前
|
新零售 供应链 搜索推荐
东郊到家预约项目系统开发源码|方案详情
实现产品个性化定制化柔性化生产,推动服务全面升级,为消费者构建“售前省心-售中用心-售后放心”
|
8月前
|
消息中间件 存储 XML
【易售小程序项目】私聊功能后端实现 (买家、卖家 沟通商品信息)【后端基于若依管理系统开发】
【易售小程序项目】私聊功能后端实现 (买家、卖家 沟通商品信息)【后端基于若依管理系统开发】
99 0
|
1月前
|
安全 BI 定位技术
同城校园外卖跑腿系统开发规则详细/需求步骤/案例设计/功能逻辑/源码版
同城校园外卖跑腿系统是为满足校园内用户对食品和商品的快速配送需求而设计的一种服务平台。
|
6月前
|
安全 小程序
人员信息管理二维码系统:扫码查看人员档案,随时补充人员信息
对于人员实名管理、来访登记、安全教育等需求,可以在草料二维码上搭建人员信息管理系统。除了扫码查看个人信息、身份证件、资格证书、劳务合同等人员档案,还可以组合表单、状态等功能组件,在二维码上展示证件状态,更新人员的奖惩、培训等情况,替代纸质记录表。
人员信息管理二维码系统:扫码查看人员档案,随时补充人员信息
|
8月前
|
存储 小程序 前端开发
【易售小程序项目】私聊功能uniapp界面实现 (买家、卖家 沟通商品信息)【后端基于若依管理系统开发】
【易售小程序项目】私聊功能uniapp界面实现 (买家、卖家 沟通商品信息)【后端基于若依管理系统开发】
102 0
|
11月前
|
安全 数据管理 测试技术
同城预约上门理疗推拿按摩系统功能开发实例源码规则解析
同城预约上门理疗推拿按摩系统功能开发实例源码规则解析
|
JSON 前端开发 Java
校园外卖点餐系统——Day04【菜品管理业务开发】
校园外卖点餐系统——Day04【菜品管理业务开发】
144 0
校园外卖点餐系统——Day04【菜品管理业务开发】
|
SQL JSON 前端开发
校园外卖点餐系统——Day02【员工管理业务开发】
校园外卖点餐系统——Day02【员工管理业务开发】
131 0
校园外卖点餐系统——Day02【员工管理业务开发】