苍穹外卖—学习记录day01

1、项目结构 

> 该项目使用分模块设计

  • Sky-take-out
    • Sky-common
    • Sky-pojo
    • Sky-server

Sky-take-out

父模块,主要在其中导入项目需要的共同依赖、统一管理依赖版本、聚合子模块

Sky-common

存放公共类、工具类、异常类等

Sky-pojo

存放实体类VO、DTO等,POJO又根据不同的功能细分为以下几个对象

Entity:和数据库中数据对应的实体类

DTO:前后端之间传输数据的对象,如JSON

VTO:视图对象,由后端提供给前端显示的数据对象

Sky-server

存放配置文件如Controller、Service、Mapper等

2、开发环境搭建

2.1远程仓库搭建

1、在IDE中通过VSGIT将项目文件所在文件夹init为一个git仓库

2、在GitHub上创建sky-take-out远程仓库,并复制ssh仓库地址

3、将初始后端代码作为version-1提交到本地仓库,再通过push提交到远程仓库的main分支

这样远程仓库搭建完成

2.2数据库创建主要表和数据

address_book : 收货地址

category:菜品分类

dish:菜品

dish_flavor:菜品风味

employee:

order_detail

orders

setmeal

setmeal_dish

shopping_cart

user

3、登录功能的开发

请求路径:localhost:8080/admin/employee/login,Post请求方式携带Json的userName和passWord

大致流程:EmployeeController接收到请求后通过employeeDTO获取到携带的userName和passWord调用employeeService中的Login方法,其中主要是调用mapper层去数据库根据用户名查信息,并对信息是否正确做判断。如果employeeService查到了正确的数据则返回employeeEntity对象给EmployeeController,Controller拿到后生成jwt令牌并将信息封装到employeeLoginVO中返回给前端

生成jwt令牌的代码

 String token = JwtUtil.createJWT(jwtProperties.getAdminSecretKey(), jwtProperties.getAdminTtl(), claims);

参数一:指定密钥

参数二:指定密钥有效时间

参数三:指定携带的自定义内容

createJWT方法

 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();
    }

4、登录拦截器的开发

作用:对非登录功能的请求做拦截操作,判断请求用户是否已登录过携带有有效令牌

4.1创建Intercepter

@Slf4j
@Component
public class AdminLoginToken implements HandlerInterceptor {
    @Autowired
    JwtProperties jwtProperties;
    //preHandle方法控制请求的拦截和放行,返回true表示放行,返回false表示拦截
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //1、获取请求中的token
        String token = request.getHeader(jwtProperties.getAdminTokenName());
        //2、判断令牌是否存在
        if(!StringUtils.hasLength(token)){
            //不存在则返回401
            log.info("无操作权限");
            response.setStatus(HttpStatus.SC_UNAUTHORIZED);
        }
        //3、存在则校验令牌是否有效
        try {
            JwtUtil.parseJWT(jwtProperties.getAdminSecretKey(), token);
        } catch (Exception e) {
            e.printStackTrace();
            log.info("令牌错误");
            response.setStatus(HttpStatus.SC_UNAUTHORIZED);
            return false;
        }
        return true;
    }

    //postHandle方法主要是做请求经过后台业务处理后,返回给前台页面之前调用操作
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

4.2MD5加密方式

java提供的方法:

DigestUtils.md5DigestAsHex("123".getBytes())

数据库提供的方法

select md5('123')

MD5加密同一个密码会是相同的结果,且MD5加密后不可逆,因此校验密码的方式就变为:将传入的密码经过MD5加密后再和数据库中密码比较

由于每个字符串通过MD5加密后都相同,因此容易被穷举法暴力解出。为了安全性设置盐添加到初始密码中,既再将密码加密之前添加一段固定/随机的字符串到密码中,再进行加密

5、Nginx

5.1反向代理

将前端对动态资源的请求,先交给Nginx,再由Nginx转发交给后端服务器

提高访问速度:如果请求访问的静态资源,则Nginx可以直接处理

提高访问性能:压缩传输中的数据,使用时解压

负载均衡:将大量的请求按照我们的配置分配到集群服务器处理

保证服务器安全:Nginx挂在外网络,服务器挂在内网。无法直接访问服务器

5.2反向代理的配置

文件位置:nginx-1.20.2\conf\ngonx.conf

location /api/ {

         proxy_pass http://localhost:8080:/admin/;

}

例如:http://localhost/api/employee  经过反向代理  http://localhost:8080/admin/employee

5.3负载均衡策略

轮询默认方式:顺序分发请求
weight        按照权重分发,权重越高分发请求越多
ip_hash根据IP分配,每个请求之后固定访问某个服务器
least_conn最少连接数分配,优先分配给现在处理请求数少的服务器
url_hash相同的url分配到同一个服务器
fair响应时间短的服务优先分配

6、使用Swagger生成接口文档

导入依赖

<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-spring-boot-starter</artifactId>
</dependency>

在配置文件配置

@Configuration
public class MyWebMvcConfig extends WebMvcConfigurationSupport {
    @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;
    
    }
    

    protected void addResourceHandlers(ResourceHandlerRegistry registry){
        //swagger会生成静态资源,这里配置swagger的静态资源位置
        registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
    }
}

配置生成的接口文档中文注释

  • @Api(tags = "接口文档中会出现该内容"):使用在Controller、Service、Mapper类上
  • @ApiModel ( tags = "接口文档中出现的中文内容" ) :使用在POJO类上
  • @ApiMpdelProperty ( tags = "接口文档中出现的中文内容" ) : 使用在类的属性上,描述属性
  • @ApiOperation ( tags = "接口文档中出现的中文内容") :使用在方法上,对方法描述
  • 13
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值