苍穹外卖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