• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
在赶路的我
博客园    首页    新随笔    联系   管理    订阅  订阅

开源项目中使用到的基础

使用注解实现重复提交

  • 若依管理系统的防止重复提交注解
  • 原理:使用java自定义注解并使用springmvc的拦截器赋予注解逻辑
@Component
public abstract class RepeatSubmitInterceptor implements HandlerInterceptor
{
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
    {
        if (handler instanceof HandlerMethod)
        {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class);
            if (annotation != null)
            {
                if (this.isRepeatSubmit(request, annotation))
                {
                    AjaxResult ajaxResult = AjaxResult.error(annotation.message());
                    ServletUtils.renderString(response, JSONObject.toJSONString(ajaxResult));
                    return false;
                }
            }
            return true;
        }
        else
        {
            return true;
        }
    }

    /**
     * 验证是否重复提交由子类实现具体的防重复提交的规则
     *
     * @param request
     * @return
     * @throws Exception
     */
    public abstract boolean isRepeatSubmit(HttpServletRequest request, RepeatSubmit annotation);
}

  • 模仿自己实现一个防止重复提交的注解

注解定义

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RepeatSubmit {
    /**
     * 定义重复提交的有效时间,默认3000s
     */
    long time() default 3000;
    /**
     * 定义消息
     */
    String msg() default "请不要重复提交";

}

拦截器定义注解逻辑

@Component
public class RepeatSubmitInterceptor implements HandlerInterceptor {

    @Autowired
    RedisService redisService;

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

        if (handler instanceof HandlerMethod){
            Method method = ((HandlerMethod) handler).getMethod();
            if (method.isAnnotationPresent(RepeatSubmit.class)){
                RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class);
                System.err.println(request.getRequestURI());
                if (isRepeat(request,annotation)){

                    response.setContentType("application/json;charset=UTF-8");
                    response.getWriter().write("不可以重复提交");
                    return false;
                }
            }
            return true;
        }else{
            return true;
        }
    }

    //验证是否是重复提交
    public boolean isRepeat(HttpServletRequest request, RepeatSubmit annotation) {
        String nowUri = request.getRequestURI();

        //所有请求的params
        Map<String, String[]> parameterMap = request.getParameterMap();
        //本次请求的时间
        long nowTime = (Long)System.currentTimeMillis();
        //封装本次请求数据,包含请求参数map和时间戳
        Map<String,Object> nowDate = new HashMap<>();
        nowDate.put("params",parameterMap);
        nowDate.put("time",nowTime);

        //读取redis中存储的请求
        String beforeDate = redisService.get(nowUri);
        if (beforeDate == null || beforeDate== "") {
            //将请求数据放入redis
            String nowDateString = null;
            nowDateString = JSON.toJSONString(nowDate);

            redisService.set(nowUri,nowDateString);
            redisService.expire(nowUri,annotation.time());
            return false;
        }else{
            //间隔时间
            long time = annotation.time();
            Map<String, Object> stringObjectMap = null;
            stringObjectMap = JSONObject.parseObject(beforeDate);

            //对比参数是否一样,时间间隔是否符合

            if (paramIsSame((Map<String,JSONArray>) stringObjectMap.get("params"),parameterMap)&&((nowTime - (Long) stringObjectMap.get("time")) < time)){
                return true;
            }
        }
        return true;
    }
    //对比参数是否一样
    public boolean paramIsSame(Map<String,JSONArray> params,Map<String,String[]> currentParams){
        //对比参数是否相同
        Set<String> keys = params.keySet();
        Set<String> currentKeys = currentParams.keySet();
        for (String key : keys) {
            if (currentKeys.contains(key)){

                JSONArray strings1 = (JSONArray) params.get(key);
                Object[] strings = strings1.toArray();
                for (int i=0;i<strings.length;i++){
                    if (strings[i].equals(currentParams.get(key)[i])){
                        continue;
                    }else{
                        return false;
                    }
                }
            }else{
                return false;
            }
        }
        return true;
    }
}

java常量设置

接口方式

  • 接口默认是public static final
public interface WeekInterface {
 
    String SUNDAY = "SUNDAY";
    String MONDAY = "MONDAY";
    String TUESDAY = "TUESDAY";
    String WEDNESDAY = "WEDNESDAY";
    String THURSDAY = "THURSDAY";
    String FRIDAY = "FRIDAY";
    String SATURDAY = "SATURDAY";
 
}

定义public static final

public class Weeks {
 
    public static final String SUNDAY = "SUNDAY";
    public static final String MONDAY = "MONDAY";
    public static final String TUESDAY = "TUESDAY";
    public static final String WEDNESDAY = "WEDNESDAY";
    public static final String THURSDAY = "THURSDAY";
    public static final String FRIDAY = "FRIDAY";
    public static final String SATURDAY = "SATURDAY";
    
}

使用枚举类enum

enum WeekEnum {  
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY  
}  

使用Serializable接口实现java对象的持久化

  • Serializable接口是一个予语义接口,被标识的类才有资格被io持久化到文本
  • serialVerisonUID是序列化和反序列化的定情信物,依靠这个标识反序列化的时候才能找到对应的java对象处理被持久化的二进制数据
  • 具体详解:Java对象为啥要实现Serializable接口? - 知乎 (zhihu.com)
posted @ 2023-08-03 22:27  在赶路的我  阅读(36)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3