ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

vue+quasar+electron+springboot+mysql撸一个TODO LIST 看板

2021-04-13 10:35:33  阅读:378  来源: 互联网

标签:mapper vue springboot quasar App set rootNode requestWrapper method


先看效果

写本项目的目的有几点:

  1. 学习下vue+electron桌面开发
  2. 学习下java和spring开发(本人一直使用PHP)
  3. 一直缺少一款能适合自己的TODO LIST软件,能有桌面端的

可直接打包成dmg、exe 等二进制文件使用。
这是我打包后的效果。

技术栈

  • vue
  • quasar
  • electron
  • springboot
  • mysql

部分后端知识

自定义注解

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginRequired {

}

自定义一个loginRequired注解,标注是否需要登录

然后在拦截器里进行全局检测

        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        LoginRequired classRequired = method.getDeclaringClass().getAnnotation(LoginRequired.class);
        // 判断接口是否需要登录
        LoginRequired methodRequired = method.getAnnotation(LoginRequired.class);
        if (classRequired == null && methodRequired == null) {
            return true;
        }
        appService.initSession(); //token 方式验证
        if (request.getSession().getAttribute(App.SESSION_USER) != null) {
            return true;
        }

@RestControllerAdvice

利用@RestControllerAdvice注解进行全局控制器异常拦截

   /**
     * ConstraintViolationException
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Response handleConstraintViolationException(MethodArgumentNotValidException ex) {
        Map<String, String> errors = new HashMap<>();
        ex.getBindingResult().getAllErrors().forEach((error) -> {
            String fieldName = ((FieldError) error).getField();
            String errorMessage = error.getDefaultMessage();
            errors.put(fieldName, errorMessage);
        });
        return new Response(ResponseRet.parametrErrror, "参数错误", errors);
    }

    /**
     * 违反约束异常 字段不为空等
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public Response handHibernateException(ConstraintViolationException ex) {
        return new Response(ResponseRet.dbExecuteFail, ex.getSQLException().toString());
    }

    @ExceptionHandler(GenericJDBCException.class)
    public Response handGenericJDBCException(GenericJDBCException ex) {
        return new Response(ResponseRet.dbExecuteFail, ex.getSQLException().toString());
    }

你可以全局处理entity定义的参数约束,或其他异常。

p6spy记录sql和耗时

    @Override
    public void onAfterExecuteQuery(PreparedStatementInformation statementInformation, long timeElapsedNanos, SQLException e) {
        App.sqlCount.set(App.sqlCount.get() + 1);
        Long duration = timeElapsedNanos / 1000000;
        App.sqlDuration.set(App.sqlDuration.get() + duration);
        Log.info(String.format("执行sql || %s 耗时 %s ms", statementInformation.getSqlWithValues(), duration));
    }

    @Override
    public void onAfterExecuteUpdate(PreparedStatementInformation statementInformation, long timeElapsedNanos, int rowCount, SQLException e) {
        App.sqlCount.set(App.sqlCount.get() + 1);
        Log.info(App.sqlCount.get().toString());
        Long duration = timeElapsedNanos / 1000000;
        App.sqlDuration.set(App.sqlDuration.get() + duration);
        String singleLineSql = statementInformation.getSqlWithValues().replaceAll("\n", "\\\\n");
        Log.info(String.format("执行sql || %s 耗时 %s ms", singleLineSql, duration));
    }

记录带所有参数的sql和执行耗时

继承DispatcherServlet记录请求参数

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request);
        ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(response);
        //创建一个 json 对象,用来存放 http 日志信息
        ObjectNode rootNode = mapper.createObjectNode();
        rootNode.put("uri", requestWrapper.getRequestURI());
        rootNode.put("clientIp", requestWrapper.getRemoteAddr());
//        rootNode.set("requestHeaders", mapper.valueToTree(getRequestHeaders(requestWrapper)));
        String method = requestWrapper.getMethod();
        String contentType = requestWrapper.getContentType();
        rootNode.put("method", method);
        try {
            super.doDispatch(requestWrapper, responseWrapper);
        } finally {
            if (method.equals("GET") || method.equals("DELETE")) {
                rootNode.set("request", mapper.valueToTree(requestWrapper.getParameterMap()));
            } else if (contentType.equals("application/x-www-form-urlencoded")) {
                rootNode.set("request", mapper.valueToTree(requestWrapper.getParameterMap()));
            } else {
                JsonNode newNode = mapper.readTree(requestWrapper.getContentAsByteArray());
                rootNode.set("request", newNode);
            }
            
            rootNode.put("status", responseWrapper.getStatus());
            JsonNode newNode = mapper.readTree(responseWrapper.getContentAsByteArray());
            rootNode.set("response", newNode);
            
            responseWrapper.copyBodyToResponse();

//            rootNode.set("responseHeaders", mapper.valueToTree(getResponsetHeaders(responseWrapper)));
            Log.info(rootNode.toString());
        }
    }

源码地址

标签:mapper,vue,springboot,quasar,App,set,rootNode,requestWrapper,method
来源: https://www.cnblogs.com/maitian2013/p/14636632.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有