Commit 6b1ddc090cec211b529f99d1cf7413a85e910ed7

Authored by 黄 x
1 parent 9b2b79bb

fix: 全局捕获validation的异常MethodArgumentNotValidException并返回正确的提示信息

  1 +package org.thingsboard.server.config.yunteng;
  2 +
  3 +import com.datastax.oss.driver.api.core.uuid.Uuids;
  4 +import lombok.RequiredArgsConstructor;
  5 +import lombok.extern.slf4j.Slf4j;
  6 +import org.apache.http.HttpHeaders;
  7 +import org.springframework.http.HttpStatus;
  8 +import org.springframework.security.core.Authentication;
  9 +import org.springframework.security.core.context.SecurityContextHolder;
  10 +import org.springframework.web.bind.MethodArgumentNotValidException;
  11 +import org.springframework.web.bind.annotation.ControllerAdvice;
  12 +import org.springframework.web.bind.annotation.ExceptionHandler;
  13 +import org.thingsboard.server.common.data.EntityType;
  14 +import org.thingsboard.server.common.data.asset.Asset;
  15 +import org.thingsboard.server.common.data.audit.ActionType;
  16 +import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
  17 +import org.thingsboard.server.common.data.exception.ThingsboardException;
  18 +import org.thingsboard.server.common.data.id.EntityId;
  19 +import org.thingsboard.server.common.data.yunteng.core.exception.*;
  20 +import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage;
  21 +import org.thingsboard.server.common.data.yunteng.dto.SysLogOperateDTO;
  22 +import org.thingsboard.server.dao.audit.AuditLogService;
  23 +import org.thingsboard.server.exception.ThingsboardErrorResponseHandler;
  24 +import org.thingsboard.server.service.security.model.SecurityUser;
  25 +import org.thingsboard.server.utils.yunteng.LogUtils;
  26 +
  27 +import javax.servlet.http.HttpServletRequest;
  28 +import javax.servlet.http.HttpServletResponse;
  29 +import java.util.Objects;
  30 +import java.util.UUID;
  31 +
  32 +@ControllerAdvice(basePackages = "org.thingsboard.server.controller.yunteng")
  33 +@RequiredArgsConstructor
  34 +@Slf4j
  35 +public class ThingsKitExceptionHandler {
  36 + private final AuditLogService auditLogService;
  37 + private final ThingsboardErrorResponseHandler errorResponseHandler;
  38 +
  39 + @ExceptionHandler(MethodArgumentNotValidException.class)
  40 + public void handleMethodArgumentNotValidException(
  41 + MethodArgumentNotValidException ex,
  42 + HttpServletRequest request,
  43 + HttpServletResponse response) {
  44 + produceLog(request, ex);
  45 + errorResponseHandler.handle(
  46 + new ThingsKitException(
  47 + ErrorMessage.INVALID_PARAMETER.setMessage(
  48 + Objects.requireNonNull(ex.getBindingResult().getFieldError()).getDefaultMessage()),
  49 + HttpStatus.BAD_REQUEST),
  50 + response);
  51 + }
  52 +
  53 + protected SecurityUser getCurrentUser() throws ThingsboardException {
  54 + Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
  55 + if (authentication != null && authentication.getPrincipal() instanceof SecurityUser) {
  56 + return (SecurityUser) authentication.getPrincipal();
  57 + } else {
  58 + throw new ThingsboardException(
  59 + "You aren't authorized to perform this operation!", ThingsboardErrorCode.AUTHENTICATION);
  60 + }
  61 + }
  62 +
  63 + /**
  64 + * 生产日志并缓存到队列中
  65 + *
  66 + * @param request 响应头
  67 + * @param e 异常信息
  68 + */
  69 + void produceLog(HttpServletRequest request, Exception e) {
  70 +
  71 + try {
  72 + SecurityUser currentUser = getCurrentUser();
  73 +
  74 + Asset entity = new Asset();
  75 + entity.setName(e.getMessage());
  76 +
  77 + // 请求相关信息
  78 + SysLogOperateDTO additionalInfo = new SysLogOperateDTO();
  79 + additionalInfo.setApi(request.getRequestURI());
  80 + additionalInfo.setClientIp(LogUtils.clientIP(request));
  81 + additionalInfo.setServerIp(LogUtils.serverIP());
  82 + additionalInfo.setUserAgent(request.getHeader(HttpHeaders.USER_AGENT));
  83 + additionalInfo.setMethod(request.getMethod());
  84 +
  85 + EntityId operateId =
  86 + new EntityId() {
  87 + @Override
  88 + public UUID getId() {
  89 + return Uuids.timeBased();
  90 + }
  91 +
  92 + @Override
  93 + public EntityType getEntityType() {
  94 + return EntityType.RUNNING_EXCEPTION;
  95 + }
  96 + };
  97 +
  98 + auditLogService.logEntityAction(
  99 + currentUser.getTenantId(),
  100 + currentUser.getCustomerId(),
  101 + currentUser.getId(),
  102 + currentUser.getName(),
  103 + operateId,
  104 + entity,
  105 + ActionType.LOG_EXCEPTION,
  106 + e,
  107 + additionalInfo);
  108 + } catch (ThingsboardException ex) {
  109 + log.error("异常日志记录异常【{}】", ex);
  110 + }
  111 + }
  112 +}
... ...