首页 > 其他分享 >苍穹外卖--开发记录day01

苍穹外卖--开发记录day01

时间:2024-10-15 22:46:19浏览次数:3  
标签:username 令牌 拦截器 String -- day01 jwt 外卖 employee

苍穹外卖day01

苍穹外卖记录day01

项目大体概况:分为用户端和商家端,商家端可以管理菜品等,用户端可以选餐购买等;

学习收获:

一:项目介绍

1:软件开发

需求分析–设计–编码–测试–运维

在这里插入图片描述

我们是开发工程师,负责代码实现

开发环境:如开发者自己的电脑。

测试环境:我们将项目部署在测试服务器,供测试人员使用。

生产环境:将项目部署到机房服务器,正式上线。

2:苍穹外卖项目介绍

苍穹外卖专门为餐饮企业定制的产品

项目主要包含商家端和用户端,分别具有这些功能。

这个我们之前说过,产品原型一般由产品经理所提出,由一些静态页面组成。

技术选型我们会用到之前spring相关的技术,也会学习一些新技术。

二:环境搭建

1:前端环境搭建

使用nginx打包前端程序可以直接运行,然后在浏览器中输入localhost就可以运行,注意!nginx要放在没有中文的目录下

2:后端环境搭建

a:项目结构

我们的后端项目基于maven来分模块开发:我们来复习一下分模块开发:分模块开发方便我们后期的维护和后期的程序的扩展

然后我们分模块开发有一个父工程,父工程的作用可以分为两块:1:继承:别的模块继承父模块之后,模块对应的依赖也会进行传递,其他模块的依赖可以在父工程中配置好,方便依赖的管理,和进行版本锁定。2:聚合:在父模块中聚合了其他的模块,我们进行打包啊之类的maven生命周期,只要通过父工程打包就可以实现全部统一打包。

除了父工程我们还有三个子工程分别是:1:common:存放一些公共类如工具类,异常类,常量类;2:pojo:存放一些实体类;

3:server:存放三层架构和配置文件等;

common中存放的一些公共,模板类;

pojo存放实体类分为三类:1::实体,存放数据库表对应的类;2:DTO:数据传输类,如json数据传输需要的对象类;

3:VO:为前端展示数据提供的类;

server主要存放的是一些三层架构;

b:使用git进行版本控制

1:首先创建本地仓库;

2:创建远程仓库;

3:将本地文件推送到git远程仓库

c:数据库环境搭建

将文档中的建表语句负责一份然后粘贴到数据库的控制台中就能创建成功了一共是11个表

d:前后端联调

初始代码中已经实现了登录功能,我们来进行测试

根据代码来解析一下登录流程:

首先发送的请求要被拦截器拦截:

所以我们定义了拦截器,并且实现拦截器接口的方法:

@Component
@Slf4j
public class JwtTokenAdminInterceptor implements HandlerInterceptor {

    @Autowired
    private JwtProperties jwtProperties;

    /**
     * 校验jwt
     *
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //判断当前拦截到的是Controller的方法还是其他资源
        if (!(handler instanceof HandlerMethod)) {
            //当前拦截到的不是动态方法,直接放行
            return true;
        }

        //1、从请求头中获取令牌
        String token = request.getHeader(jwtProperties.getAdminTokenName());

        //2、校验令牌
        try {
            log.info("jwt校验:{}", token);
            Claims claims = JwtUtil.parseJWT(jwtProperties.getAdminSecretKey(), token);
            Long empId = Long.valueOf(claims.get(JwtClaimsConstant.EMP_ID).toString());
            log.info("当前员工id:", empId);
            //3、通过,放行
            return true;
        } catch (Exception ex) {
            //4、不通过,响应401状态码
            response.setStatus(401);
            return false;
        }
    }
}

在拦截器中我们进行令牌的校验:先获取令牌,提供parser来解析令牌,如果解析保存就返回401响应码,如果成功就放行;

我们指定拦截器需要注册来设置拦截的路径:

@Configuration
@Slf4j
public class WebMvcConfiguration extends WebMvcConfigurationSupport {

    @Autowired
    private JwtTokenAdminInterceptor jwtTokenAdminInterceptor;

    /**
     * 注册自定义拦截器
     *
     * @param registry
     */
    protected void addInterceptors(InterceptorRegistry registry) {
        log.info("开始注册自定义拦截器...");
        registry.addInterceptor(jwtTokenAdminInterceptor)
                .addPathPatterns("/admin/**")
                .excludePathPatterns("/admin/employee/login");
    }
}

在代码中我们看到代码注册了jwt拦截器,拦截除了登录路径外的所有路径;

我们现在是登录请求,拦截器放行后我们进入controller层

@PostMapping("/login")
public Result<EmployeeLoginVO> login(@RequestBody EmployeeLoginDTO employeeLoginDTO) {
    log.info("员工登录:{}", employeeLoginDTO);

    Employee employee = employeeService.login(employeeLoginDTO);

    //登录成功后,生成jwt令牌
    Map<String, Object> claims = new HashMap<>();
    claims.put(JwtClaimsConstant.EMP_ID, employee.getId());
    String token = JwtUtil.createJWT(
            jwtProperties.getAdminSecretKey(),
            jwtProperties.getAdminTtl(),
            claims);

    EmployeeLoginVO employeeLoginVO = EmployeeLoginVO.builder()
            .id(employee.getId())
            .userName(employee.getUsername())
            .name(employee.getName())
            .token(token)
            .build();

    return Result.success(employeeLoginVO);
}

分析一下我们接收的是一个DTO实体类,这个实体类中只包含用户名和密码,正是我们登录需要的;然后我们调用service的login方法返回的是一个员工对象;登录成功后我们要生成jwt令牌,调用工具类中的生成jwt的方法;然后返回一个VO数据展示类;可以看到一个类是jwtproperties类

@Component
@ConfigurationProperties(prefix = "sky.jwt")
@Data
public class JwtProperties {

    /**
     * 管理端员工生成jwt令牌相关配置
     */
    private String adminSecretKey;
    private long adminTtl;
    private String adminTokenName;

    /**
     * 用户端微信用户生成jwt令牌相关配置
     */
    private String userSecretKey;
    private long userTtl;
    private String userTokenName;

}

这是一个配置类,返回的就是在配置文件中前缀为‘sky.jwt’的属性值;

然后我们继续看controller调用了service的什么方法呢:

public Employee login(EmployeeLoginDTO employeeLoginDTO) {
    String username = employeeLoginDTO.getUsername();
    String password = employeeLoginDTO.getPassword();

    //1、根据用户名查询数据库中的数据
    Employee employee = employeeMapper.getByUsername(username);

    //2、处理各种异常情况(用户名不存在、密码不对、账号被锁定)
    if (employee == null) {
        //账号不存在
        throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
    }

    //密码比对
    // TODO 后期需要进行md5加密,然后再进行比对
    if (!password.equals(employee.getPassword())) {
        //密码错误
        throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
    }

    if (employee.getStatus() == StatusConstant.DISABLE) {
        //账号被锁定
        throw new AccountLockedException(MessageConstant.ACCOUNT_LOCKED);
    }

    //3、返回实体对象
    return employee;
}

这个方法就是先换取DTO对象的属性值,然后再调用mapper中的方法,返回的是一个emp对象,含义就是通过用户名去查找员工信息;然后我们再进行正确性判断,如果为空说明不存在,不为空就返回;

然后我们最后再看mapper的代码:

@Mapper
public interface EmployeeMapper {

    /**
     * 根据用户名查询员工
     * @param username
     * @return
     */
    @Select("select * from employee where username = #{username}")
    Employee getByUsername(String username);

}

然后我们再进行正确性判断,如果为空说明不存在,不为空就返回;

然后我们最后再看mapper的代码:

@Mapper
public interface EmployeeMapper {

    /**
     * 根据用户名查询员工
     * @param username
     * @return
     */
    @Select("select * from employee where username = #{username}")
    Employee getByUsername(String username);

}

很简单,就是使用select语句查找员工对象然后返回给service层;


总结

今天主要学习了软件开发的流程,熟悉了一下项目结构,对前端和后端环境进行了搭建,但是还有部分没搭建完,等明天继续搭建。

标签:username,令牌,拦截器,String,--,day01,jwt,外卖,employee
From: https://blog.csdn.net/2301_79748665/article/details/142965186

相关文章

  • 【ICPC】The 2021 ICPC Asia Shanghai Regional Programming Contest H
    LifeisaGame#最小生成树#重构树#图论#贪心题目描述Agoodproblemshouldhaveaconcisestatement.Youaregivenanarrayaaaoflength......
  • C++互斥锁
    互斥锁(Mutex,全称:MutualExclusion)是一种用于多线程编程中的同步机制,用来确保在同一时刻只有一个线程可以访问共享资源。它通过锁定机制防止多个线程同时对共享资源进行读写操作,从而避免数据竞争和不一致性问题。互斥锁的核心思想是保证互斥访问,即当一个线程持有互斥锁并正在访问......
  • 实验2 C语言分支与循环基础应用编程-1
    实验一:#include<stdio.h>#include<stdlib.h>#include<time.h>#defineN5#defineN1397#defineN2476#defineN321intmain(){intcnt;intrandom_major,random_no;srand(time(NULL));cnt=0;while(cnt......
  • C语言中的指针与内存管理:两种情况分析
    在C语言中,指针的使用和内存管理是非常重要的概念。在本文中,我们将分析两种情况:一种是通过指针修改结构体内容,另一种是错误地尝试通过指针分配新的内存。我们将详细探讨这两种情况中的内存管理问题和如何避免常见的错误。第一例:通过指针修改结构体内容以下是第一段代码:#includ......
  • 2024/10/15日工作总结
    听写32个单词,阅读一篇英文日报;完成离散课后作业;优化验证码代码:importjavax.swing.;importjava.awt.;importjava.awt.event.MouseEvent;importjava.awt.event.MouseListener;importjava.util.Random;//Graphics图形绘制抽象类,绘制直线、矩形、椭圆等//Graphics2D继承......
  • 2024-10-15
    CSS简介点击查看代码<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>Document&l......
  • [2023 CSP-J]题目思考与反思
    小Y的桌子上放着\(n\)个苹果从左到右排成一列,编号为从\(1\)到\(n\\\)。小苞是小Y的好朋友,每天她都会从中拿走一些苹果。\(\\\)每天在拿的时候,小苞都是从左侧第\(1\)个苹果开始、每隔\(2\)个苹果拿走\(1\)个苹果。随后小苞会将剩下的苹果按原先的顺序重新排成一......
  • 10.15日
    1.上层界面设计(UI设计)Swing提供了多个组件(如按钮、标签、文本框等),通过这些组件,你可以构建用户可视化交互的界面。关键组件JFrame:代表主窗口,所有其他组件都放置在JFrame中。JPanel:用于分隔不同的UI区域,可以嵌套使用。JButton、JLabel、JTextField:分别用于创建按钮、文......
  • 软件测试笔记
    (1)需求测试需求:需求文档,制作的需求书(全称:软件需求规格说明书,简称:srs)需求:根据客户要实现一个功能;开发根据需求编写代码,测试也是根据需求编写测试用例和测试案例:测试制作水杯的说明书测试:需求是否合理,需求有没错别字,需求是否规范,需求是否具有唯一性等(2)界面测试界面测试也是外观测......
  • noip多校联考总结
    noip多校联考总结10.14T1不知道考场在干嘛,打了一个暴力,用了卡时,但是卡时在不同系统下单位不同,还好评测时环境与我本机的相同,clock函数都是以毫秒为单位的,谨记以后要写if(clock()/CLOCKS_PER_SEC>=0.95)break;而不是类似于if(clock()>=950)break;,纯属运气比较好,要是在正式考......