Sky苍穹外卖总结

Serializable的用处

类实现了Serializable接口才能被序列化,Serializable接口内无内容,起标记作用,序列化主要在类被ObjectInputStream存储时发生,类如果没实现Serializable接口则无法被序列化,报java.io.NotSerializableException异常

Swagger构架的注解及作用
如何生成接口文档

官网:https://swagger.io/

  • 引入依赖
<dependency>
      <groupId>com.github.xiaoymin</groupId>
      <artifactId>knife4j-spring-boot-starter<artifactId>
</dependency>
  • 声明配置类
@Configuration
@Slf4j
public class WebMvcConfiguration extends WebMvcConfigurationSupport {
    /**
     * 通过knife4j生成接口文档
     * @return
     */
    @Bean
    public Docket docket1() {
        ApiInfo apiInfo = new ApiInfoBuilder()
                .title("苍穹外卖项目接口文档")
                .version("2.0")
                .description("苍穹外卖项目接口文档")
                .build();
        Docket docket = new Docket(DocumentationType.SWAGGER_2)
                .groupName("管理端接口")
                .apiInfo(apiInfo)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.sky.controller.admin"))
                .paths(PathSelectors.any())
                .build();
        return docket;
    }
实体类相关注解
  • @ApiModel注解
    标记实体类代表的是什么,回显到doc.html
  • @ApiModelProperty注解
    标记实体类中属性表示的内容,回显到doc.html
@Data
@ApiModel(description = "员工登录时传递的数据模型")
public class EmployeeLoginDTO implements Serializable {

    @ApiModelProperty("用户名")
    private String username;

    @ApiModelProperty("密码")
    private String password;

}
Controller相关注解
  • @Api注解
    用于描述Controller
  • @ApiOperation注解
    用于描述Controller中的方法
@RestController
@RequestMapping("/admin/category")
@Api(tags = "分类相关接口")
@Slf4j
public class CategoryController {
    @Autowired
    private CategoryService categoryService;
    /**
     * 新增分类
     * @param categoryDTO
     * @return
     */
    @PostMapping
    @ApiOperation("新增分类")
    public Result<String> save(@RequestBody CategoryDTO categoryDTO){
        log.info("新增分类:{}", categoryDTO);
        categoryService.save(categoryDTO);
        return Result.success();
    }
}
Lombok插件及其注解
  • Lombok的引用:在pom.xml中引入以下代码
  <dependency>
      //加个版本
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
  </dependency>
  • @Getter,@Setter
    给实体类增加get和set方法
  • @Synchronized
    作用范围是方法,自动把方法添加到同步机制,锁的不是方法,锁的是方法内代码块
  • @NonNull
    该注解快速判断是否为空,如果为空,则抛出java.lang.NullPointerException
  • @Data
    该注解相当于同时加上以下注解@Setter @Getter,@ToString,@EqualsAndHashCode,@NoArgsConstructor作用于类中使用。
  • @ToString
    该方法大家应该非常熟悉,但需要注意的是:@ToString有多个属性可以进一步设置:
    callSuper 是否输出父类的toString方法,默认为false
    includeFieldNames 是否包含字段名称,默认为true
    exclude 排除生成tostring的字段
    代码实现:
@ToString(callSuper = true,exclude ={"name"})
public class Person {
    private String name;
    private String address;  
}
  • @Cleanup
    用于确保IO流被关闭,帮助关闭IO流。
    代码:
public void testCleanUp() {
    try {
        @Cleanup ByteArrayOutputStream baos = new ByteArrayOutputStream();
        baos.write(new byte[] {'Y','e','s'});
        System.out.println(baos.toString());
    } catch (IOException e) {
        e.printStackTrace();
    }
}
  • @EqualsAndHashCode
    生成toString和hashCode方法
  • @NoArgsConstructor
    无参构造
  • @AllArgsConstructor
    全参构造
  • @NoArgsConstructor
    生成包含final和@NonNull的无参构造方法
  • @Builder
    构造器方法
    代码:
@Test
public void testUser() {
    User6 user6 = User6.builder()
       .id(1)
       .username("itbaizhan")
       .password("itbaizhan")
       .build();
}
  • @Slf4j,@Log
    各种日志注解
  • @SneakyThrows
    作用于方法体上方用于捕捉和抛出异常
  • @Value
    @Value注解和@Data类似,区别在于它会把所有成员变量默认定义为private final修饰,并且不会生成set方法。更适合只读性的类。
  • @Delegate
    被@Delegate注释的属性,会把这个属性类型的公有非静态方法合到当前类
  • @Singluar
    不知道QAQ
事务的开启
  • 启动类上添加@EnableTransactionManagement
  • 在访问数据库的Service方法上添加注解 @Transactional 便可
@EnableCaching开启缓存与Redis
  • @EnableCaching放置在Springboot启动类上用于开启缓存。
  • @Cacheable放在需要缓存返回值的Controller方法上
  • Redis配置需要配置类和yml参数
Interceptor拦截器
  • 编写拦截器类,实现HandlerInterceptor接口
    代码:
@Component
@Slf4j
public class JwtTokenUserInterceptor 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.getUserTokenName());

        //2、校验令牌
        try {
            //log.info("jwt校验:{}", token);
            Claims claims = JwtUtil.parseJWT(jwtProperties.getUserSecretKey(), token);
            Long userId = Long.valueOf(claims.get(JwtClaimsConstant.USER_ID).toString());
            BaseContext.setCurrentId(userId);
            //log.info("当前用户id{}", userId);
            //3、通过,放行
            return true;
        } catch (Exception ex) {
            //4、不通过,响应401状态码
            response.setStatus(401);
            return false;
        }
    }
}
  • 配置类中注册自定义拦截器
    代码:
@Autowired
    private JwtTokenAdminInterceptor jwtTokenAdminInterceptor;
    /**
     * 注册自定义拦截器
     *
     * @param registry
     */
    protected void addInterceptors(InterceptorRegistry registry) {
        log.info("开始注册自定义拦截器...");
        registry.addInterceptor(jwtTokenAdminInterceptor)
                .addPathPatterns("/admin/**")
                .excludePathPatterns("/admin/employee/login");
        registry.addInterceptor(jwtTokenUserInterceptor)
                .addPathPatterns("/user/**")
                .excludePathPatterns("/user/user/login")
                .excludePathPatterns("/user/shop/status");
    }
全局异常处理器
  • 工作原理为Interceptor/AOP
  • @RestControllerAdvice
    写在全局异常处理器类上,用于声明全局异常处理器
  • @ExceptionHandler
    写在处理类的方法上,用于异常类处理
定时任务处理器SpringTask
  • @EnableScheduling放在启动类上,开启定时任务
  • @Scheduled(cron = "0 * * * * ? ")放在定时任务方法上,开启定时方法。
@Component
@Slf4j
public class OrderTask {
    @Autowired
    private OrderMapper orderMapper;
    @Scheduled(cron = "0 * * * * ? ")
    public void processTimeoutOrder(){
        log.info("定时处理超时订单:{}", LocalDateTime.now());
        LocalDateTime time= LocalDateTime.now().plusMinutes(-15);
        List<Orders> ordersList=orderMapper.getByStatusAndOrderTime(Orders.PENDING_PAYMENT,time);
        if(ordersList!=null && !ordersList.isEmpty()){
            for (Orders orders : ordersList) {
                orders.setStatus(Orders.CANCELLED);
                orders.setCancelReason("订单超时,自动取消");
                orders.setCancelTime(LocalDateTime.now());
                orderMapper.update(orders);
            }
        }
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不见长安在

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值