线程,lambda,依赖包命令,定时任务锁,比较时间,跨域配置,存储对象OOS,参数校验

线程三种创建方式

①继承Thread类,重写run()方法(不能抛出异常),单继承,不能继承其他类,所以资源不能共享;
②实现Runnable接口,重写run()方法,可以继承其他类,进而共享同一个目标对象;
③实现Callable接口,重写call()方法(可以抛出异常),有返回值,通过callable任务可以拿到Future对象,获得计算结果。
其中,start()方法用来开启线程,但不会立马结束,会进入可执行状态,需要获取到CPU使用权才会执行;run()方法是由jvm创建,本地操作系统回调的方法,不能手动调用。

lambda 表达式使用

List<User> list = Arrays.asList(
                new User((long) 100,"zhangsan",3,"qwe"),
                new User((long) 104,"zhangwu",3,"qwe"),
                new User((long) 101,"lisi",4,"asdaf"));
               //输出用户集合中名字以“z"开头的名字
        list.stream()
                .filter(p->p.getName().startsWith("z"))
                .forEach(p-> System.out.println(p.getName()));
        User user = new User((long)1,"zhangyi",1,null);
        Optional<User> userOption = Optional.ofNullable(user);
        //夺命连环null检查
        System.out.println(userOption.map(o->o.getName())
                .map(n->n.toUpperCase())
                .orElse(null));

查看依赖包之间的关系

执行以下命令

mvn dependency:tree

spring boot使用定时任务锁

引入定时任务锁依赖

<!-- shedlock定时任务锁 -->
        <dependency>
            <groupId>net.javacrumbs.shedlock</groupId>
            <artifactId>shedlock-spring</artifactId>
            <version>4.30.0</version>
        </dependency>
        <dependency>
            <groupId>net.javacrumbs.shedlock</groupId>
            <artifactId>shedlock-provider-jdbc-template</artifactId>
            <version>4.30.0</version>

创建表结构(一定要使用改表名字和字段,源码已封装)

CREATE TABLE `shedlock` (
  `name` varchar(64) NOT NULL,
  `lock_until` timestamp(3) NULL DEFAULT NULL,
  `locked_at` timestamp(3) NULL DEFAULT NULL,
  `locked_by` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`name`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='shedlock分布式定时任务表';

启动配置类上加上如下注解

@EnableSchedulerLock(defaultLockAtMostFor = "PT60S")//定时任务锁,设置默认时间60S
@EnableScheduling  // 开启定时功能的注解

编写配置类

import net.javacrumbs.shedlock.core.LockProvider;
import net.javacrumbs.shedlock.provider.jdbctemplate.JdbcTemplateLockProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
@Component
public class ShedLockConfig {
    @Bean
    public LockProvider lockProvider(DataSource dataSource) {

        return new JdbcTemplateLockProvider(dataSource);
    }

}

编写定时任务

@Component
@Slf4j
public class remindJob {
    @Autowired
    RemindService remindService;
    /**
     * 每天执行一次,每天晚上12点
     */
    @Scheduled(cron = "0 0 0 * * *")
    @SchedulerLock(name = "remindJob", lockAtMostForString = "PT60S", lockAtLeastForString = "PT60S")
    public void dingShi() {
        LocalDateTime localDateTime = LocalDateTime.now();
        XxlJobLogger.log("开始搜寻 RemindService. 今日:" + localDateTime);
        log.info("[RemindJobHandler] 定时job开始");
        Tip tip = remindService.getRemindJob();
        log.info("[RemindJobHandler] 完成条数 tip = {}", JSONUtils.toJSONString(tip));
    }

name:定时任务的名字,就是数据库中的内个主键
lockAtMostFor:锁的最大时间单位为毫秒
lockAtMostForString:最大时间的字符串形式,例如:PT60S 代表60秒
lockAtLeastFor:锁的最小时间单位为毫秒
lockAtLeastForString:最小时间的字符串形式

时间对比

获取明日0时0分0秒

LocalDate localDate = LocalDate.now();
// 当前日期+1
localDate = localDate.plusDays(1);
LocalDateTime dateTime = LocalDateTime.of(localDate.getYear(), localDate.getMonth(), localDate.getDayOfMonth(), 0, 0, 0);

时间比大小

现在的时间是否大于dateTime,是返回true,不是返回false

LocalDateTime.now().isAfter(dateTime)

拿数据库的时间来对比

只获取今天的时间

QueryWrapper<Remind> queryWrapper = new QueryWrapper<>();
//只显示今日的提醒
LocalDate localDate = LocalDate.now();
LocalDateTime jintian = LocalDateTime.of(localDate.getYear(),localDate.getMonth(),localDate.getDayOfMonth(),0,0,0);
localDate = localDate.plusDays(1);
LocalDateTime mingtian = LocalDateTime.of(localDate.getYear(),localDate.getMonth(),localDate.getDayOfMonth(),0,0,0);
queryWrapper.between(Remind.REMIND_DATE,jintian,mingtian);

配置跨域

package com.guli.getway.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;

@Configuration //gateway
public class corsConfig {

    @Bean//添加过滤器
    public CorsWebFilter corsWebFilter(){
        // 基于url跨域,选择reactive包下的,不然return会报错
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        // 跨域配置信息
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        // 允许跨域的头
        corsConfiguration.addAllowedHeader("*");
        // 允许跨域的请求方式
        corsConfiguration.addAllowedMethod("*");
        // 允许跨域的请求来源
        corsConfiguration.addAllowedOrigin("*");
        // 是否允许携带cookie跨域
        corsConfiguration.setAllowCredentials(true);
        // 任意url都要进行跨域配置
        source.registerCorsConfiguration("/**",corsConfiguration);
        return new CorsWebFilter(source);
    }
}

配置阿里云存储对象OOS

添加依赖

<dependency>
	<groupId>com.alibaba.cloud</groupId>
	<artifactId>spring-cloud-alicloud-oss</artifactId>
	<version>2.1.1.RELEASE</version>
</dependency>

yaml配置OOS存储对象信息

具体信息需要登录阿里云存储对象管制台和AccessKey管理查看具体信息

spring:
  cloud:
    alicloud:
      access-key: LTAI5tFAKaXnDVsNqZmoTL    #阿里云云账号密钥
      secret-key: DNNc4sxqbd2lkimKZX5VElwyf6yZ  #阿里云云账号密钥
      oss:
        endpoint: https://oss-cn-guanhou.aliyuncs.com  #存储对象的域名地址

代码

通过签名和秘钥给前端上传数据让前端直接上传文件到存储对象OOS

package com.guli.disanfang.controller;

import com.aliyun.oss.OSS;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

@RestController
@RequestMapping("third-service/oss")
public class OSSController {

    @Autowired
    private OSS ossClient;

    @Value("${spring.cloud.alicloud.oss.bucket}")
    private String bucket;
    @Value("${spring.cloud.alicloud.oss.endpoint}")
    private String endpoint;
    @Value("${spring.cloud.alicloud.access-key}")
    private String accessId;

    private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

    @GetMapping("/policy")
    public Map<String, String> getPolicy(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String host = "https://" + bucket + "." + endpoint; // host的格式为 bucketname.endpoint
        // callbackUrl为上传回调服务器的URL,请将下面的IP和Port配置为您自己的真实信息。
        //        String callbackUrl = "http://88.88.88.88:8888";


        String dir = format.format(new Date())+"/"; // 用户上传文件时指定的前缀。以日期格式存储

        // 创建OSSClient实例。
        Map<String, String> respMap= null;
        try {
            long expireTime = 30;
            long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
            Date expiration = new Date(expireEndTime);
            // PostObject请求最大可支持的文件大小为5 GB,即CONTENT_LENGTH_RANGE为5*1024*1024*1024。
            PolicyConditions policyConds = new PolicyConditions();
            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
            policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);

            String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);//生成协议秘钥
            byte[] binaryData = postPolicy.getBytes("utf-8");
            String encodedPolicy = BinaryUtil.toBase64String(binaryData);
            String postSignature = ossClient.calculatePostSignature(postPolicy);

            respMap = new LinkedHashMap<String, String>();
            respMap.put("accessid", accessId);
            respMap.put("policy", encodedPolicy);//生成的协议秘钥
            respMap.put("signature", postSignature);
            respMap.put("dir", dir);
            respMap.put("host", host);
            respMap.put("expire", String.valueOf(expireEndTime / 1000));
            // respMap.put("expire", formatISO8601Date(expiration));


        } catch (Exception e) {
            // Assert.fail(e.getMessage());
            System.out.println(e.getMessage());
        } finally {
            ossClient.shutdown();
        }
        return respMap;
    }
}

JSR303数据校验

引入依赖

如果springboot有引入就不用引入了

<!--jsr3参数校验器-->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-validation</artifactId>
</dependency>

实体类参数校验

在这里插入图片描述
controller

    /**
     * 保存
     */
    @RequestMapping("/save")
    //@Valid打开校验规则
    public R save(@Valid @RequestBody PmsBrandEntity pmsBrand){
//        List<FieldError> fieldErrors = bindingResult.getFieldErrors();
//        if (!StringUtils.isEmpty(fieldErrors)){
//            Map<String, String> map = new HashMap<>();
//            fieldErrors.forEach(item->{
//                map.put(item.getField(), item.getDefaultMessage());
//            });
//            return R.error(400,"参数异常!").put("error",map);
//        }
        pmsBrandService.save(pmsBrand);

        return R.ok();
    }

分组校验参数

添加校验接口(controller判断是哪个校验接口,分组对哪个接口生效)

//更新校验
public interface UpdateVail {}

//新增校验
public interface AddVail {}

参数校验
在这种情况下,没有指定分组的校验注解,默认是不起作用的。想要起作用就必须要加groups

@NotNull(message = "修改必须定制品牌id", groups = {UpdateVailGroup.class})
@Null(message = "新增不能指定id", groups = {AddVailGroup.class})
private Long brandId;

业务方法参数上使用@Validated注解,并用@Validated指定使用校验的接口标识
在这里插入图片描述

统一异常

@RestControllerAdvice(basePackages = "com.guli.shangpin.controller" )
@Slf4j
public class conExceptionAdv {
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public R conException(MethodArgumentNotValidException e){
        Map<String,String> map = new HashMap<>();
        e.getBindingResult().getFieldErrors().forEach(item->{
            map.put(item.getField(), item.getDefaultMessage());
        });
        log.error("消息提示{},类型{}",e.getMessage(),e.getClass());
        return R.error(CodeMessage.CANSHU_ERROR.getCode(),CodeMessage.CANSHU_ERROR.getMessage()).put("data",map);
    }
}

异常枚举

public enum CodeMessage {
    CANSHU_ERROR(10001,"参数异常!"),
    WEIZHI_ERROR(10000,"未知错误!");

     private int code;
     private String message;
     CodeMessage(int code, String message){
        this.code = code;
        this.message=message;
    }

    public int getCode(){
        return code;
    }
    public String getMessage(){
        return message;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值