java项目经验总结

本文分享了Java项目开发中的实用技巧,包括获取系统时间戳、格式化时间、使用ThreadLocal存储线程共享信息、事务机制处理、数据库小数运算、常量定义、业务实现方式以及防止接口幂等性等方面的内容,还提及了Spring Security和Redis的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.如果对精度要求不高的情况下使用如下方式获得系统时间戳。原理连接

System.out.println(LocalDateTime.now());

2.如果需要获得格式化的时间,或者将字符串转换成日期格式,按如下方式进行书写。原理连接

public class TestMain {
    public static final DateTimeFormatter dateTimeFormatter=DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");

    public static void main(String[] args) {
        String test=TestMain.dateTimeFormatter.format(LocalDateTime.now());
        System.out.println(test);
    }

3.在线程中可以使用threadlocal放置线程中共享的信息。

public class UserInfoThreadlocal {
    private static final ThreadLocal<Long> threaslocal = new ThreadLocal<>();
    public static void put(Long userId) {
        remove();
        threaslocal.set(userId);
    }
    public static Long get() {
        return threaslocal.get();
    }
    public static void remove() {
        threaslocal.remove();
    }
}

这是本人在项目中使用的方式,在对jwt进行权限验证通过以后会将一些线程共享的信息放入ThreadLocal中,springsecurity实际上使用的也是threadlocal进行权限验证。

4.为了让事务机制起作用,当service调用service方法的时候选择创建新的service,例如AService非事务方法需要调用事务方法,则创建一个Bservice,然后将BService注入到AService中。

5.数据库中的小数使用Decimal,mysql中的Decimal采用的是字符串存贮的方式,在java中使用BigDecimal进行运算,BigDecimal底层使用BigInt存储数据,BigInt使用int[]数组来存储数据。

6.可以使用枚举类定义常量。

public enum TransStatusEnum {
    SUCCSEE(10, "交易成功"),

    LOADING(20, "交易中"),

    FAIL(30, "交易失败"),

    CancelOrder(40,"撤单"),

    OrderFinish(50, "售卖结束");

    private Integer status;
    private String desc;

    private TransStatusEnum(Integer status, String desc) {
        this.status = status;
        this.desc = desc;
    }
    
    public static TransStatusEnum getEnumByStatus(Integer code) {
        for (TransStatusEnum temp : TransStatusEnum.values()) {
            if (code == temp.getStatus()) {
                return temp;
            }
        }
        return TransStatusEnum.LOADING;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public  String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public static String getDesc(Integer i){
        return getEnumByStatus(i).getDesc();
    }
}

7.使用拦截器和注解结合的方式来完成业务。

/**
 * 不校验token
 * @see
 */
@Documented
@Inherited
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface NoVerificationToken {

}
@Component
@Slf4j
public class TokenInterceptor extends HandlerInterceptorAdapter {
    @Autowired
    private TokenService tokenService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {

        // 获取方法上的注解
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();

        PenguinLogThreadLocal.remove();

        if (method.isAnnotationPresent(NoVerificationToken.class)) {
            return true;
        }

8.使用一次性token来防止接口的幂等性

@PostMapping("/repeatLimNo")
    @ApiOperation(value = "获取请求序列", notes = "获取请求序列--拦截重复请求")
    public Outcome<String> getToken(@RequestHeader(value = "token") String token, HttpServletRequest request) {
        return Outcome.success("", repeatLimiterSeq.generateSeq());
    }

该接口返回一个唯一的请求序列放在redis中,请求一次失效,在需要防止接口幂等性的接口上传送,且该字段为必传字段。

    @Override
    public String generateSeq() {
        //使用UUID生成 token
        String token = UUID.randomUUID().toString();
        token=token.replaceAll("-","");
        //存入Redis,key:token,过期时间10分钟
        redisUtil.set("repeatLimNo::"+token,token,20*60);
        PenguinLogThreadLocal.setParam(token);
        return token;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值