查漏补缺内容
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.聚合
<modules>
<module>../tlias-utils</module>
<module>../tlias-web-management</module>
<module>../tlias-pojo</module>
</modules>
注意:聚合工程中所包含的模块,在构建时,会自动根据模块间的依赖关系设置构建顺序,与聚合工程中模块的配置书写位置无关。
JWT
简介:
定义了一种简洁的、自包含的格式,用于在通信双方以 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 技术选型
技术选型:展示项目中使用到的技术框架和中间件等