Day01 【苍穹外卖】环境搭建和前后端联调

2023-12-20 06:57:53

一、苍穹外卖简介

项目采用前后端分离的方式开发,包括前端界面(Web端管理程序、小程序客户端界面)前端vue技术开发使用nginx部署启动,后端springboot技术开发IDEA进行启动。

二、项目联调和配置

1、前端web界面

前端项目使用nginx启动,只需要将打包后的vue项目放到nginx安装目录下的html文件夹下。然后对nginx.conf文件进行配置即可启动前端vue,浏览器使用localhost:80即可访问相关界面。

在这里插入图片描述

2、前后端联调实现登录

思考:本项目采用前后端分离的方式开发,前端的浏览器发送的请求是如何请求到后端服务的?
前端请求地址:http://localhost/api/employee/login
后端接口地址:http://localhost:8080/admin/employee/login

前端请求:打开浏览器的调试,Network下的Headers即可看到前端请求的url:http://localhost/api/employee/login
在这里插入图片描述
后端配置文件:application.yml

server:
  port: 8080
#当前环境为dev开发环境,因此application-dev.yml配置文件也生效
spring:
  profiles:
    active: dev 
  main:
    allow-circular-references: true
  datasource:
    druid:
      driver-class-name: ${sky.datasource.driver-class-name}
      url: jdbc:mysql://${sky.datasource.host}:${sky.datasource.port}/${sky.datasource.database}?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
      username: ${sky.datasource.username}
      password: ${sky.datasource.password}

mybatis:
  #mapper配置文件
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.sky.entity
  configuration:
    #开启驼峰命名
    map-underscore-to-camel-case: true

logging:
  level:
    com:
      sky:
        mapper: debug
        service: info
        controller: info

sky:
  jwt:
    # 设置jwt签名加密时使用的秘钥
    admin-secret-key: itcast
    # 设置jwt过期时间
    admin-ttl: 7200000
    # 设置前端传递过来的令牌名称
    admin-token-name: token

配置文件:application-dev.yml

sky:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    host: localhost
    port: 3306
    database: sky_take_out
    username: root
    password: 12345678

后端接收请求:当后端接收登录请求时,后端接口地址:http://localhost:8080/admin/employee/login

/**
 * 员工管理EmployeeController 
 */
@RestController
@RequestMapping("/admin/employee")
@Slf4j
public class EmployeeController {
    @Autowired
    private EmployeeService employeeService;
    @Autowired
    private JwtProperties jwtProperties;
    // 登录请求
    @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);
    }
}

解答:采用Nginx做反向代理,将前端发送的动态请求由Nginx转发到后端服务器。
在这里插入图片描述
Nginx反向代理的好处:提升访问速度、进行负载均衡、保障后端服务安全。

3、反向代理配置

#将匹配到的/api/的前端请求转发到http://localhost:8080/admin/请求地址,后面动态的请求 
server {
        listen 80; #监听的端口
        server_name  localhost; #监听的域名
        # 反向代理,处理管理端发送的请求
        location /api/ {
        	#反向代理关键proxy_pass指令
			proxy_pass   http://localhost:8080/admin/; #指令将请求转发到代理的后端服务器
        }
}

配置说明:当nginx接收到前端请求含有/api/时,nginx将请求转发到http://localhost:8080/admin/的后端服务器请求路径下响应,动态请求路径拼接在http://localhost:8080/admin/后即可,如下图。
在这里插入图片描述

4、负载均衡

负载均衡的前提是反向代理,将接收到的请求均衡的分配到各应用服务器上

upstream webservers{
	  server 127.0.0.1:8080 weight=90 ;
	  server 127.0.0.1:8088 weight=10 ;
	}
#将匹配到的/api/的前端请求转发到http://localhost:8080/admin/请求地址,后面动态的请求 
server {
        listen 80; #监听的端口
        server_name  localhost; #监听的域名
        # 反向代理,处理管理端发送的请求
        location /api/ {
        	#负载均衡
			#proxy_pass   http://webservers/admin/; #指令将请求转发到的后端服务器
        }
}

nginx负载均衡策略:
在这里插入图片描述

5、密码加密存储

为了保护用户的隐私和数据安全,密码一般不使用明文存储,此处使用md5加密算法进行加密。

/**
 * 员工登录
 *
 * @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);
    }

    //密码比对
    //对用户登录的密码做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);
    }

    //3、返回实体对象
    return employee;
}

6、导入接口文档

作为前后端分离的项目,接口的设计非常重要,下面是前后端分离开发流程:
在这里插入图片描述
对于json格式的接口,使用http://yapi.lootom-ai.com/login导入接口文件。

7、Swagger 测试

Swagger是一款可以根据resutful风格生成的生成的接口开发文档,并且支持做测试的一款中间软件。
Knife4j是一个集Swagger2 和 OpenAPI3为一体的增强解决方案。教程:knife4j使用教程
在这里插入图片描述

<!--1、引入Knife4j的官方start包,该指南选择Spring Boot版本<3.0,开发者需要注意-->
<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-openapi2-spring-boot-starter</artifactId>
    <version>4.4.0</version>
</dependency>
/**
 * 配置类,注册web层相关组件
 */
@Configuration
@Slf4j
public class WebMvcConfiguration extends WebMvcConfigurationSupport {
    /**
     * 2、通过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;
    }

    /**
     * 3、设置静态资源映射
     * @param registry
     */
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        log.info("开始设置静态资源映射....");
        registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
}

所有配置结束后,重启SpringBoot服务,打开浏览器:http://localhost:8080/doc.html即可查看相关的接口文档。
在这里插入图片描述

思考:通过 Swagger 就可以生成接口文档,那么我们就不需要 Yapi了?
1、Yapi是设计阶段使用的工具,管理和维护接口;
2、Swagger 在开发阶段使用的框架,帮助后端开发人员做后端的接口测试;

8、Swagger常用注解

注解说明
@Api用在类,例如Controller,表示类的说明
@ApiModel用在类,例如entity,DTO,VO
@ApiModelProperty用在属性,描述属性信息
@ApiOperation用在方法上,例如Controller的方法,例如方法的用途、作用

在这里插入图片描述
在这里插入图片描述
标注后,重启服务,打开浏览器:http://localhost:8080/doc.html即可查看。
在这里插入图片描述

文章来源:https://blog.csdn.net/weixin_46081857/article/details/135060064
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。