开发环境搭建_后端环境搭建_熟悉项目结构
constant:存储的是定义好的常量类
context:存储与上下文相关的
enumeration:存储枚举类
exception:存储一些异常
json:处理一些json转换的类
properties:存储一些配置类
result:存储一些后端的返回结果
utils:存储一些工具类
开发环境搭建_后端环境搭建_使用Git进行版本控制
首先,用gitignore忽略掉不需要上传的文件内容:
在本地创建本地仓库:
在菜单栏选择创建你本地git仓库,选定根目录的地址。再将本地代码提交给本地仓库。
创建远程仓库:
复制仓库地址url,并创建新的远程,建立新的远程分支
直接选择推送,代码就推送成功了。
后端环境搭建_数据库环境搭建
有专门的数据库建表文档可以查看
后端环境搭建_前后端联调
在这里主要是启动了nginx,前后端联调测试了以下员工登录功能是否成功
(这一段代码我将解析的十分详细,因为使用了很多的常量类枚举类自定义异常,我需要快速熟悉并适应这样成熟化的书写格式)
/**
* 登录
*
* @param employeeLoginDTO
* @return
*/
@PostMapping("/login")
public Result<EmployeeLoginVO> login(@RequestBody EmployeeLoginDTO employeeLoginDTO) {
log.info("员工登录:{}", employeeLoginDTO);
Employee employee = employeeService.login(employeeLoginDTO);
代码解析:定义了一个login方法用于实现登录功能,使用@Requestbody注解将前端传输到的json转换为对应的可接收的dto对象。
在以前我们没有具体明确Result类返回的到底是什么类型的返回值,现在有了各种VO的明确建立,我们则需要在Result的泛型当中具体明确我们所需要的具体的VO对象
然后创建了一个employee对象用于接收employeeService调用login方法得到的结果
login方法的具体实现如下:
/**
* 员工登录
*
* @param employeeLoginDTO
* @return
*/
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;
}
}
先是创建了两个string类型的对象用于存储获取到的用户名和密码,然后用获取到的用户名调用employeeMapper中的getByUsername方法获取到具体数据,并用employee将数据保存。接下来进行的是数据判断:
如果用户不存在,抛出一个我们定义好的异常类AccountFoundException,被使用super关键字传给这个异常类的父类的msg内容是我们定义好的常量类中的一个常量 ACCOUNT_NOT_FOUND
这个常量的具体内容如下:
public static final String ACCOUNT_NOT_FOUND = "账号不存在";
然后判断密码是否存在,该账号是否被锁定,如果一切ok,将我们存储好信息的employee对象返回给controller执行后续代码。
//登录成功后,生成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);
登录成功后,借助我们获取到的employee对象,我们借助jwtUtil工具类生成了用于登录校验的token,并将需要返回的对象内容借助employeeLoginVo来存储。以标准的VO来进行返回。
可以看到我们这里对于数据的存储方式不在是new一个对象来挨个调用getset方法存储了,而是直接选择用.builder()来实现。借助 .+参数名(获取到信息的对象.方法)的格式来快速实现数据存储。
这样的方法有两个需要注意的点:
在存储完所有信息只有要加上.build();来结尾。
在存储对象employeeLoginVo中,需要有@Builder注解才可以调用这个build方法。
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(description = "员工登录返回的数据格式")
public class EmployeeLoginVO implements Serializable {
@ApiModelProperty("主键值")
private Long id;
@ApiModelProperty("用户名")
private String userName;
@ApiModelProperty("姓名")
private String name;
@ApiModelProperty("jwt令牌")
private String token;
}
至此,登陆方法结束。
后端环境搭建_前后端联调_Nginx反向代理和负载均衡
我们需要思考一个问题:
前端发送的请求是如何到达后端的呢?
我们会发现,我们前端和后端的请求路径url并不是相同的,二者并没有匹配到
实际上呢,是nginx反向代理在发力:
Nginx反向代理和负载均衡的具体实现步骤:
在这个配置后,请求路径会被替换然后传输给tomcat服务器
location的意思是需要处理的特殊请求。下图中是表示对包含有api的请求进行特殊处理。
这负载均衡跟反向代理的区别是什么呢?
主要是在上文中的webservers字段,这个字段一个在upstream后,一个在路径当中。这个字段是不固定的,但要保证这两个位置的字段要完全相同
这样接收到的请求就会以某种策略来传输给这两个服务器中了。
开发环境搭建_完善登录功能
代码实现如下:
//密码比对
//进行md5加密,然后再进行比对
password = DigestUtils.md5DigestAsHex(password.getBytes());
if (!password.equals(employee.getPassword())) {
//密码错误
throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
}
if (employee.getStatus() == StatusConstant.DISABLE) {
//账号被锁定
throw new AccountLockedException(MessageConstant.ACCOUNT_LOCKED);
}
导入接口文档
项目当中使用Yapi来进行对接口文档的保存和使用。但是2025年发现yapi已经无法使用了。本人使用的是Apifox
里面的接口也都可以直接使用
Swagger_介绍和使用方式
maven坐标如下
<!--对swagger封装-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>${knife4j}</version>
</dependency>
在配置类中配置knife4j的配置内容如下:
/**
* 通过knife4j生成接口文档
* @return
*/
@Bean
public Docket docket() {
ApiInfo apiInfo = new ApiInfoBuilder()
.title("苍穹外卖项目接口文档")
.version("2.0")
.description("苍穹外卖项目接口文档")
.build();
Docket docket = new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo)
.select()
.apis(RequestHandlerSelectors.basePackage("com.sky.controller"))
.paths(PathSelectors.any())
.build();
return docket;
}
在配置类中设置资源映射如下:
/**
* 设置静态资源映射
* @param registry
*/
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
在这里,如果我们访问到/doc.html结尾的路径,就可以到我们的接口文档控制台中去了
我们发现,在swagger当中也可以实现接口文档的测试功能,那么:
Swagger_常用注解
没什么好讲的,当一个开发规范用就行,在对应的地方上写对应的注解,你的swagger上就可以生成出规范的接口文档。