瑞吉外卖知识点总结
Posted 硅谷工具人
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了瑞吉外卖知识点总结相关的知识,希望对你有一定的参考价值。
文章目录
1. 手机验证码功能实现
1.1 业务流程:
(1)业务端输入手机号,点击发送
(2)后台接收请求,验证手机号,生成验证码。
这里要注意验证码是在后台生成好的。我原来一直以为手机里的验证码是运营商生成的,原来是错误的。
(3)将生成验证码并通过阿里云接口向指定的手机号发送。
(4)手机接收到验证码后,填写到前端,登录
(5)后台根据前端填写的验证码和手机号和后端去匹配,如果一致就通过,否则,返回错误信息。
1.2 依赖包
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.5.16</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
<version>2.1.0</version>
</dependency>
1.3 工具类
阿里短信的工具类,最后一个param就是传入后台生成的验证吗。
package com.guigutool.reggie.utils;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
/**
* 短信发送工具类
*/
public class SMSUtils
/**
* 发送短信
* @param signName 签名
* @param templateCode 模板
* @param phoneNumbers 手机号
* @param param 参数
*/
public static void sendMessage(String signName, String templateCode,String phoneNumbers,String param)
DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", "", "");
IAcsClient client = new DefaultAcsClient(profile);
SendSmsRequest request = new SendSmsRequest();
request.setSysRegionId("cn-hangzhou");
request.setPhoneNumbers(phoneNumbers);
request.setSignName(signName);
request.setTemplateCode(templateCode);
request.setTemplateParam("\\"code\\":\\""+param+"\\"");
try
SendSmsResponse response = client.getAcsResponse(request);
System.out.println("短信发送成功");
catch (ClientException e)
e.printStackTrace();
1.4 登录案例实现
(1) 点击发送验证码按钮,后端的处理
@Autowired
private RedisTemplate redisTemplate;
@PostMapping("/sendMsg")
public R<String> sendMsg(@RequestBody User user, HttpSession session)
//获取手机号
String phone = user.getPhone();
if(StringUtils.isNotEmpty(phone))
//生成随机的4位验证吗
String code = ValidateCodeUtils.generateValidateCode(4).toString();
log.info("code:", code);
//调用阿里云提供的短信API完成发送短信
SMSUtils.sendMessage("Reggie","",phone,code);
//需要将生成的验证码保存到Session
//session.setAttribute(phone,code);
//将生成的验证码保存到Redis中,并且设置有效期为5分钟
redisTemplate.opsForValue().set(phone,code,5, TimeUnit.MINUTES);
return R.success("验证码发送成功");
return R.error("验证码发送失败");
(2) 填写验证码后,登录处理
/**
* 移动端用户登录
* @param map
* @param session
* @return
*/
@PostMapping("/login")
public R<User> login(@RequestBody Map map, HttpSession session)
String phone = map.get("phone").toString();
String code = map.get("code").toString();
// Object codeInSession = session.getAttribute(phone);
//从redis中获取缓存的验证码
Object codeInSession = redisTemplate.opsForValue().get(phone);
if(Objects.nonNull(codeInSession) && codeInSession.equals(code))
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(User::getPhone,phone);
User user = userService.getOne(queryWrapper);
if(Objects.isNull(user))
user = new User();
user.setPhone(phone);
user.setStatus(1);
userService.save(user);
//登录成功
session.setAttribute(SystemConstant.MOBILE_USER_ID,user.getId());
//如果用户登录成功,则删除Redis中缓存的验证码
redisTemplate.delete(phone);
return R.success(user);
return R.error("登录失败");
2. 缓存
2.1 Cache缓存
SpringCache是一个基于注解的缓存功能,只要简单的加一个注解,就能实现缓存功能。
SpringCache也提供了一层抽象接口,底层可以切换不同的cache实现类,接口名称是CacheManager。
CacheManager是Spring提供的各种缓存技术抽象接口。
以下是一些一些不同的实现类:
CacheManager | 描述 |
---|---|
EhCacheCacheManager | 使用EhCache作为缓存技术 |
GuavaCacheManager | 使用Google的GuavaCache作为缓存技术 |
RedisCacheManager | 使用Redis作为缓存技术 |
2.2 SpringCache缓存使用
(1)默认配置
只要加入spring-boot-starter-web,就会存在SpringCache的配置。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>compile</scope>
</dependency>
默认有以下4个实现类,所以可以不做任何改动。
(2) 在启动应用主程序添加@EnableCaching注解
(3) 注入
//Ctrl+Alt+鼠标左点击,可查看该接口的实现类
@Autowired
private CacheManager cacheManager;
(4)注解说明
注解 | 说明 | 用途 |
---|---|---|
@EnableCaching | 开启缓存注解功能 | 全部配置,在启动app类上注解 |
@Cacheable | 在方法执行前spring先查看缓存中是否有数据,如果有数据,则直接返回缓存数据;若没有数据,调用方法并将方法返回值放到缓存中 | 查询操作 |
@CachePut | 将方法的返回值放到缓存中 | 保存或者修改操作 |
@CacheEvict | 将一条或者多条记录从缓存中删除 | 删除操作 |
(5)使用案例
定义缓存的名称
private final String cacheName = "userCache";
保存操作
/**
* cachePut:将方法返回值放入缓存
* value: 缓存的名称,每个缓存名称下可以有多个key
* key:缓存的key, 这个取自于方法的返回值
* 例如:这里的key使用的是返回的user对象的id
*/
@CachePut(value=cacheName, key = "#result.id")
@PostMapping
public User save(User user)
userService.save(user);
return user;
删除操作
/**
* 这里的key使用的是传入的参数
* @param id
*/
@CacheEvict(value = cacheName, key="#id")
@DeleteMapping("/id")
public void delete(@PathVariable Long id)
userService.removeById(id);
修改操作
// @CacheEvict(value = cacheName, key="#p0.id") (1)根据接收的参数设置的key
// @CacheEvict(value = cacheName, key="#user.id") (2)根据接收的参数设置的key
// @CacheEvict(value = cacheName, key="#root.args[0].id") (3)根据接收的参数设置的key
// @CacheEvict(value = cacheName, key="#result.id") (4)根据返回的值设置的key
@CacheEvict(value = cacheName, key="#result.id")
@PutMapping
public User update(User user)
userService.updateById(user);
return user;
查询操作
condition 满足条件时,才缓存
/**
* condition: 条件,满足条件时,才缓存数据
* unless: 满足条件,不缓存 #注意这里会发生缓存穿透,就是当用户查询的数据不存在时,会一直调用sql,如果有太多的请求请数据库发送sql语句,也会加重数据库的负载
*/
@Cacheable(value = cacheName,key="#id", condition = "#result != null")
@GetMapping("/id")
public User getById(@PathVariable Long id)
User user = userService.getById(id);
return user;
unless: 满足条件时,不缓存
/**
* condition: 条件,满足条件时,才缓存数据
* unless: 满足条件,不缓存 #注意这里会发生缓存穿透,就是当用户查询的数据不存在时,会一直调用sql,如果有太多的请求请数据库发送sql语句,也会加重数据库的负载
*/
@Cacheable(value = cacheName,key="#id", unless = "#result == null")
@GetMapping("/id")
public User getById(@PathVariable Long id)
User user = userService.getById(id);
return user;
@Cacheable(value = cacheName, key = "#user.id+':'+#user.name")
@GetMapping("/list")
public List<User> list(User user)
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Objects.nonNull(user.getName()),User::getName, user.getName());
List<User> userList = userService.list(wrapper);
return userList;
2.3 SpringRedis缓存
添加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
yml添加:
spring:
redis:
host: 127.0.0.1
port: 6379
database: 0
cache:
redis:
time-to-live: 1800000 #设置缓存有效期
从SpringCache缓存切换到Redis缓存,只需要修改配置即可。
3. 接口文档Swagger
3.1 增强版本
使用增强功能knife4j
(1) Pom配置
<!-- 增强swagger-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
(2) WebMvc配置
/**
* @Author: KingWang
* @Date: 2023/3/7
* @Desc:
**/
@Slf4j
@Configuration
@EnableSwagger2
@EnableKnife4j
public class WebMvcConfig extends WebMvcConfigurationSupport
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry)
log.info("开始静态资源映射..");
registry.addResourceHandler("/backend/**").addResourceLocations("classpath:/backend/");
registry.addResourceHandler("/front/**").addResourceLocations("classpath:/front/");
//swagger文档需要添加下面2行
registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
@Bean
public Docket createRestApi()
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.guigutool.reggie.controller"))
.paths(PathSelectors.any())
.build();
public ApiInfo apiInfo()
return new ApiInfoBuilder()
.title("瑞吉外卖")
.version("1.0")
.description("瑞吉外卖接口文档")
.build();
(3) 过滤中放行静态资源访问权限
LoginCheckFilter中的doFilter方法,如果不放行,则需要登录后才可以查看doc.html。
@Override
protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException
log.info("拦截到请求:", request.getRequestURI());
//1. 获取本次请求的URI
String requestURI = request.getRequestURI();
//2.定义不需要处理的请求路径
String[] urls = new String[]
"/employee/login",
"/employee/logout",
"/backend/**",
"/front/**",
"/common/**",
"/user/sendMsg", //移动端发送短信
"/user/login", //移动端登录
"/doc.html", //生成swagger api文件,这里不放行,在登录后,也可以查看
"/webjars/**",
"/swagger-resources",
"/v2/api-docs"
;
//其他内容省略...
(4) 接口文档查看
地址:http://localhost:8080/doc.html#/home
3.2 常用Swagger注解
注解 | 说明 |
---|---|
@Api | 用于请求的类上,例如Controller,表示对类的说明 |
@ApiModel | 用在类上,通常是实体类,表示一个返回响应数据的信息 |
@ApiModelProperty | 用在属性上,描述响应类的属性 |
@ApiOperation | 用在请求的方法上,说明方法的用途,作用 |
@ApiImplicitParams | 用在请求的方法上,表示一组参数说明 |
@ApiImplicitParam | 用在@ApiImplicitParams注解中,指定一个请求参数的各个方面 |
3.3 Swagger注解实例
(1)实体类注解
/**
* 套餐
*/
@Data
@ApiModel("套餐")
public class Setmeal implements Serializable
private static final long serialVersionUID = 1L;
@ApiModelProperty("主键Id")
private Long id;
@ApiModelProperty("分类Id")
private Long categoryId;
@ApiModelProperty("套餐名称")
private String name;
@ApiModelProperty("套餐价格")
private BigDecimal price;
@ApiModelProperty("状态 0:停用 1:启用")
private Integer status;
@ApiModelProperty("编码")
private String code;
@ApiModelProperty("描述信息")
private String description;
@ApiModelProperty("图片")
private String image;
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
@TableField(fill = FieldFill.INSERT)
private Long createUser;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Long updateUser;
//是否删除
private Integer isDeleted;
(2)Controller注解
/**
* @Author: KingWang
* @Date: 2023/3/14
* @Desc:
**/
@RequestMapping("/setmeal")
@Slf4j
@RestController
@Api(tags="套餐相关接口")
public class SetmealController
private final String cacheName = "setmealCache";
@Autowired
private SetmealDishService setmealDishService;
@Autowired
private SetmealService setmealService;
@Autowired
private CategoryService categoryService;
@Autowired
private RedisTemplate redisTemplate;
/**
* 新增套餐
* @param setmealDto
* @return
*/
@ApiOperation(value = "新增套餐")
@PostMapping
@CacheEvict(value = cacheName, allEntries = true)
public R<String> save(@RequestBody SetmealDto setmealDto)
setmealService.saveWithDish(setmealDto);
Set keys = redisTemplate.keys("setmeal:*");
redisTemplate.delete(keys)黑马瑞吉外卖——
黑马瑞吉外卖项目部分知识总结,对项目中的难点、不熟悉内容、项目亮点以及bug进行记录与分享。以及项目中用到的设计思想进行总结
黑马瑞吉外卖项目部分知识总结,对项目中的难点、不熟悉内容、项目亮点以及bug进行记录与分享。以及项目中用到的设计思想进行总结
以上是关于瑞吉外卖知识点总结的主要内容,如果未能解决你的问题,请参考以下文章
黑马Java笔记+踩坑汇总JavaSE+JavaWeb+SSM+SpringBoot+瑞吉外卖+SpringCloud/SpringCloudAlibaba+黑马旅游+谷粒商城