苍穹外卖(一)

 查漏补缺内容

Maven高级

1.分模块设计

为什么
将项目 按照功能拆分成若干个子模块,方便项目的管理维护、扩展,也方便模块间的相互调用,资源共享。

创建 maven 模块 tlias-pojo ,存放实体类。
创建 maven 模块 tlias -utils ,存放相关工具类
注意: 分模块开发需要先针对模块功能进行设计,再进行编码。不会先将工程开发完毕,然后进行拆分
拆分之后,如果要使用拆分之前模块的功能,可以引入对应模块的依赖
例如在tlias-web-management中重新引入tlias-pojo和tlias-utils:

<!--        tlias-pojo-->
        <dependency>
            <groupId>com.itheima</groupId>
            <artifactId>tlias-pojo</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

<!--        tlias-utils-->

        <dependency>
            <groupId>com.itheima</groupId>
            <artifactId>tlias-utils</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

2.继承

概念: 继承 描述的是两个工程间的关系,与 java 中的继承相似,子工程可以继承父工程中的配置信息,常见于依赖关系的继承
作用: 简化依赖配置 统一管理依赖
实现: <parent> … </parent>

. 创建maven模块 tlias-parent ,该工程为父工程,设置打包方式pom(默认jar)

. 子工程pom.xml文件中,配置继承关系。

. 父工程中配置各个工程共有的依赖(子工程会自动继承父工程的依赖)。

关于不同打包方式:

jar:普通模块打包,springboot项目基本都是jar包(内嵌tomcat运行)

war:普通web程序打包,需要部署在外部的tomcat服务器中运行

pom:父工程或聚合工程,该模块不写代码,仅进行依赖管理

继承关系实现

. 创建maven模块 tlias-parent ,该工程为父工程,设置打包方式pom

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.itheima</groupId>
    <artifactId>tlias-parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

. 子工程pom.xml文件中,配置继承关系。

<parent>
        <groupId>com.itheima</groupId>
        <artifactId>tlias-parent</artifactId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../tlias-parent/pom.xml</relativePath>

    </parent>


    <artifactId>tlias-pojo</artifactId>
    <version>1.0-SNAPSHOT</version>

其余类似与tlias-pojo。

注意:

  • 在子工程中,配置了继承关系之后,坐标中的groupId是可以省略的,因为会自动继承父工程的 。
  • relativePath指定父工程的pom文件的相对位置(如果不指定,将从本地仓库/远程仓库查找工程)。

. 父工程中配置各个工程共有的依赖(子工程会自动继承父工程的依赖)

<dependencies>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.30</version>
        </dependency>

    </dependencies>

注意:l若父子工程都配置了同一个依赖的不同版本,以子工程的为准。

版本锁定

在maven中,可以在父工程的pom文件中通过 <dependencyManagement> 来统一管理依赖版本

父工程

<dependencyManagement>
        <dependencies>


            <!--mybatis起步依赖-->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis.version}</version>
            </dependency>





            <!--PageHelper分页插件-->
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper-spring-boot-starter</artifactId>
                <version>1.4.2</version>
            </dependency>

            <!--阿里云OSS-->




            <!--JWT令牌-->
            <dependency>
                <groupId>io.jsonwebtoken</groupId>
                <artifactId>jjwt</artifactId>
                <version>0.9.1</version>
            </dependency>

            <!--fastJSON-->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.76</version>
            </dependency>





        </dependencies>





    </dependencyManagement>

子工程

<dependencies>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            
        </dependency>

    </dependencies>

注意:子工程引入依赖时,无需指定 <version> 版本号,父工程统一管理。变更依赖版本,只需在父工程中统一变更。

自定义属性/引用属性

<properties>
       
        <mybatis.version>2.2.2</mybatis.version>
    </properties>
<dependencyManagement>
        <dependencies>


            <!--mybatis起步依赖-->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis.version}</version>
            </dependency>
 </dependencies>


    </dependencyManagement>

1. < dependencyManagement > < dependenc ies > 的区别是什么 ?
l < dependenc ies > 是直接依赖 , 在父工程配置了依赖 , 子工程会直接继承下来
l < dependencyManagement > 是统一管理依赖版本 , 不会直接依赖, 还需要在子工程中引入所需依赖 ( 无需指定版本 )

3.聚合

maven 中可以通过 < modules > 设置当前聚合工程所包含的子模块名称
<modules>
        <module>../tlias-utils</module>
        <module>../tlias-web-management</module>
        <module>../tlias-pojo</module>
    </modules>

注意:聚合工程中所包含的模块,在构建时,会自动根据模块间的依赖关系设置构建顺序,与聚合工程中模块的配置书写位置无关。

在父模块的生命周期中点击pakage就可以完成打包操作

JWT

简介:

全称: J SON  W eb  T oken JSON Web Tokens - jwt.io
定义了一种简洁的、自包含的格式,用于在通信双方以 json 数据格式安全的传输信息。由于数字签名的存在,这些信息是可靠的。
组成:
第一部分: Header( 头), 记录令牌类型、签名算法等。 例如: {"alg":"HS256","type":"JWT"}
第二部分: Payload( 有效载荷),携带一些 自定义 信息 默认信息等。 例如: {"id":"1","username":"Tom"}
第三部分: Signature( 签名),防止 Token 被篡改、确保安全性。将 header payload ,并加入指定秘钥,通过指定签名算法计算而来。

引入依赖

<!--JWT令牌-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>

JwtUtils工具类

package com.sky.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Map;

public class JwtUtil {
    /**
     * 生成jwt
     * 使用Hs256算法, 私匙使用固定秘钥
     *
     * @param secretKey jwt秘钥
     * @param ttlMillis jwt过期时间(毫秒)
     * @param claims    设置的信息
     * @return
     */
    public static String createJWT(String secretKey, long ttlMillis, Map<String, Object> claims) {
        // 指定签名的时候使用的签名算法,也就是header那部分
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

        // 生成JWT的时间
        long expMillis = System.currentTimeMillis() + ttlMillis;
        Date exp = new Date(expMillis);

        // 设置jwt的body
        JwtBuilder builder = Jwts.builder()
                // 如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的
                .setClaims(claims)
                // 设置签名使用的签名算法和签名使用的秘钥
                .signWith(signatureAlgorithm, secretKey.getBytes(StandardCharsets.UTF_8))
                // 设置过期时间
                .setExpiration(exp);

        return builder.compact();
    }

    /**
     * Token解密
     *
     * @param secretKey jwt秘钥 此秘钥一定要保留好在服务端, 不能暴露出去, 否则sign就可以被伪造, 如果对接多个客户端建议改造成多个
     * @param token     加密后的token
     * @return
     */
    public static Claims parseJWT(String secretKey, String token) {
        // 得到DefaultJwtParser
        Claims claims = Jwts.parser()
                // 设置签名的秘钥
                .setSigningKey(secretKey.getBytes(StandardCharsets.UTF_8))
                // 设置需要解析的jwt
                .parseClaimsJws(token).getBody();
        return claims;
    }

}

Intercepter

概念:是一种动态拦截方法调用的机制,类似于过滤器。 Spring 框架中提供的,用来动态拦截控制器方法的执行。
作用:拦截请求,在指定的方法调用前后,根据业务需要执行预先设定的代码。

步骤

获取请求 url
判断请求 url 中是否包含 login ,如果包含,说明是登录操作,放行。
获取请求头中的令牌( token )。
判断令牌是否存在,如果不存在,返回错误结果(未登录)。
解析 token ,如果解析失败,返回错误结果(未登录)。
放行。
package com.itheima.interceptor;

import com.alibaba.fastjson.JSONObject;
import com.itheima.pojo.Result;
import com.itheima.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Slf4j
@Component
public class LoginCheckInterceptor implements HandlerInterceptor {
    @Override //目标资源方法运行前运行, 返回true: 放行, 放回false, 不放行
    public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {
        //1.获取请求url。
        String url = req.getRequestURL().toString();
        log.info("请求的url: {}",url);

        //2.判断请求url中是否包含login,如果包含,说明是登录操作,放行。
        if(url.contains("login")){
            log.info("登录操作, 放行...");
            return true;
        }

        //3.获取请求头中的令牌(token)。
        String jwt = req.getHeader("token");

        //4.判断令牌是否存在,如果不存在,返回错误结果(未登录)。
        if(!StringUtils.hasLength(jwt)){
            log.info("请求头token为空,返回未登录的信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换 对象--json --------> 阿里巴巴fastJSON
            String notLogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notLogin);
            return false;
        }

        //5.解析token,如果解析失败,返回错误结果(未登录)。
        try {
            JwtUtils.parseJWT(jwt);
        } catch (Exception e) {//jwt解析失败
            e.printStackTrace();
            log.info("解析令牌失败, 返回未登录错误信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换 对象--json --------> 阿里巴巴fastJSON
            String notLogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notLogin);
            return false;
        }

        //6.放行。
        log.info("令牌合法, 放行");
        return true;
    }

    @Override //目标资源方法运行后运行
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle ...");
    }

    @Override //视图渲染完毕后运行, 最后运行
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion...");
    }
}

前言

项目的整体概述

(一)管理端-外卖商家使用

(二)用户端-点餐用户使用

(三)可以增长的能力

1.软件开发整体介绍

1.1 软件开发流程

1.2 角色分工

  • 项目经理:对整个项目负责,任务分配、把控进度
  • 产品经理:进行需求调研,输出需求调研文档、产品原型等
  • UI设计师:根据产品原型输出界面效果图
  • 架构师:项目整体架构设计、技术选型等
  • 开发工程师:代码实现
  • 测试工程师:编写测试用例,输出测试报告
  • 运维工程师:软件环境搭建、项目上线 

1.3 软件环境

  • 开发环境(development):开发人员在开发阶段使用的环境,一般外部用户无法访问
  • 测试环境(testing):专门给测试人员使用的环境,用于测试项目,一般外部用户无法访问
  • 生产环境(production):即线上环境,正式提供对外服务的环境

2.苍穹外卖项目介绍 

2.1 项目介绍

定位:专门为餐饮企业(餐厅、饭店)定制的一款软件产品

功能架构:体现项目中的业务功能模块

2.2 产品原型

产品原型:用于展示项目的业务功能,一般由产品经理进行设计

2.3 技术选型

技术选型:展示项目中使用到的技术框架和中间件等

  • 21
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值