VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > Java教程 >
  • vue+quasar+electron+springboot+mysql撸一个TODO LIST 看板

先看效果

写本项目的目的有几点:

  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());
 
}
 
}

源码地址

  • 前端 https://github.com/visonforcoding/carambola-todo
  • 后端 https://github.com/visonforcoding/carambola-todo-service
出  处:https://www.cnblogs.com/maitian2013/p/14636632.html

相关教程