package jnpf.exception; import cn.dev33.satoken.exception.SameTokenInvalidException; import cn.dev33.satoken.exception.NotLoginException; import cn.dev33.satoken.exception.NotPermissionException; import cn.dev33.satoken.exception.NotRoleException; import com.alibaba.fastjson.JSON; import jnpf.base.ActionResult; import jnpf.base.ActionResultCode; import jnpf.base.LogSortEnum; import jnpf.base.UserInfo; import jnpf.config.ConfigValueUtil; import jnpf.database.util.NotTenantPluginHolder; import jnpf.entity.LogEntity; import jnpf.service.LogService; import jnpf.util.*; import jnpf.util.data.DataSourceContextHolder; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.web.ErrorProperties; import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController; import org.springframework.boot.web.servlet.error.DefaultErrorAttributes; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.validation.ObjectError; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @author JNPF开发平台组 * @version V3.1.0 * @copyright 引迈信息技术有限公司 * @date 2021/3/16 10:10 */ @Slf4j @Controller @ControllerAdvice public class ResultException extends BasicErrorController { @Autowired private UserProvider userProvider; @Autowired private LogService logService; @Autowired private ConfigValueUtil configValueUtil; public ResultException(){ super(new DefaultErrorAttributes(), new ErrorProperties()); } @ResponseBody @ExceptionHandler(value = LoginException.class) public ActionResult loginException(LoginException e) { ActionResult result = ActionResult.fail(ActionResultCode.Fail.getCode(), e.getMessage()); return result; } @ResponseBody @ExceptionHandler(value = ImportException.class) public ActionResult loginException(ImportException e) { ActionResult result = ActionResult.fail(ActionResultCode.Fail.getCode(), e.getMessage()); return result; } // @ResponseBody // @ExceptionHandler(value = FileNotException.class) // public ActionResult loginException(FileNotException e) { // ActionResult result = ActionResult.fail(ActionResultCode.Fail.getCode(), "文件不存在"); // return result; // } /** * 自定义异常内容返回 * * @param e * @return */ @ResponseBody @ExceptionHandler(value = DataException.class) public ActionResult dataException(DataException e) { ActionResult result = ActionResult.fail(ActionResultCode.Fail.getCode(), e.getMessage()); return result; } /// // @ResponseBody // @ExceptionHandler(value = SQLSyntaxErrorException.class) // public ActionResult sqlException(SQLSyntaxErrorException e) { // ActionResult result; // log.error(e.getMessage()); // e.printStackTrace(); // if (e.getMessage().contains("Unknown database")) { // printLog(e, "请求失败"); // result = ActionResult.fail(ActionResultCode.Fail.getCode(), "请求失败"); // } else { // printLog(e, "数据库异常"); // result = ActionResult.fail(ActionResultCode.Fail.getCode(), "数据库异常"); // } // return result; // } // // @ResponseBody // @ExceptionHandler(value = SQLServerException.class) // public ActionResult sqlServerException(SQLServerException e) { // ActionResult result; // printLog(e, "系统异常"); // if (e.getMessage().contains("将截断字符串")) { // printLog(e, "某个字段字符长度超过限制,请检查。"); // result = ActionResult.fail(ActionResultCode.Fail.getCode(), "某个字段字符长度超过限制,请检查。"); // } else { // log.error(e.getMessage()); // printLog(e, "数据库异常,请检查。"); // result = ActionResult.fail(ActionResultCode.Fail.getCode(), "数据库异常,请检查。"); // } // return result; // } @ResponseBody @ExceptionHandler(value = MethodArgumentNotValidException.class) public ActionResult methodArgumentNotValidException(MethodArgumentNotValidException e) { Map map = new HashMap<>(16); List allErrors = e.getBindingResult().getAllErrors(); for (int i = 0; i < allErrors.size(); i++) { String s = allErrors.get(i).getCodes()[0]; //用分割的方法得到字段名 String[] parts = s.split("\\."); String part1 = parts[parts.length - 1]; map.put(part1, allErrors.get(i).getDefaultMessage()); } String json = JSON.toJSONString(map); ActionResult result = ActionResult.fail(ActionResultCode.ValidateError.getCode(), json); printLog(e, "字段验证异常"); return result; } @ResponseBody @ExceptionHandler(value = WorkFlowException.class) public ActionResult workFlowException(WorkFlowException e) { if (e.getCode() == 200) { List> list = JsonUtil.getJsonToListMap(e.getMessage()); return ActionResult.success(list); } else { return ActionResult.fail(e.getMessage()); } } @ResponseBody @ExceptionHandler(value = WxErrorException.class) public ActionResult wxErrorException(WxErrorException e) { return ActionResult.fail(e.getError().getErrorCode(), "操作过于频繁"); } @ResponseBody @ExceptionHandler(value = ServletException.class) public void exception(ServletException e) throws Exception { log.error("系统异常:" + e.getMessage(), e); printLog(e, "系统异常"); throw new Exception(); } @ResponseBody @ExceptionHandler(value = Exception.class) public ActionResult exception(Exception e) { log.error("系统异常:" + e.getMessage(), e); printLog(e, "系统异常"); return ActionResult.fail(ActionResultCode.Fail.getCode(), "系统异常"); } /** * 权限码异常 */ @ResponseBody @ExceptionHandler(NotPermissionException.class) public ActionResult handleNotPermissionException(NotPermissionException e) { return ActionResult.fail(ActionResultCode.Fail.getCode(), "没有访问权限,请联系管理员授权"); } /** * 角色权限异常 */ @ResponseBody @ExceptionHandler(NotRoleException.class) public ActionResult handleNotRoleException(NotRoleException e) { return ActionResult.fail(ActionResultCode.ValidateError.getCode(), "没有访问权限,请联系管理员授权"); } /** * 认证失败 */ @ResponseBody @ExceptionHandler(NotLoginException.class) public ActionResult handleNotLoginException(NotLoginException e) { return ActionResult.fail(ActionResultCode.SessionOverdue.getCode(), "认证失败,无法访问系统资源"); } /** * 无效认证 */ @ResponseBody @ExceptionHandler(SameTokenInvalidException.class) public ActionResult handleIdTokenInvalidException(SameTokenInvalidException e) { return ActionResult.fail(ActionResultCode.SessionOverdue.getCode(), "无效内部认证,无法访问系统资源"); } private void printLog(Exception e, String module) { try { UserInfo userInfo = userProvider.get(); if (userInfo.getId() == null) { e.printStackTrace(); return; } //接口错误将不会进入数据库切源拦截器需要手动设置 if (configValueUtil.isMultiTenancy() && DataSourceContextHolder.getDatasourceId() == null) { DataSourceContextHolder.setDatasource(userInfo.getTenantId(), userInfo.getTenantDbConnectionString(), userInfo.isAssignDataSource()); } LogEntity entity = new LogEntity(); entity.setId(RandomUtil.uuId()); entity.setType(LogSortEnum.Operate.getCode()); entity.setUserId(userInfo.getUserId()); entity.setUserName(userInfo.getUserName() + "/" + userInfo.getUserAccount()); if (!ServletUtil.getIsMobileDevice()) { String modelName = module; entity.setModuleName(modelName); } StringBuilder sb = new StringBuilder(); sb.append(e.toString() + "\n"); StackTraceElement[] stackArray = e.getStackTrace(); for (int i = 0; i < stackArray.length; i++) { StackTraceElement element = stackArray[i]; sb.append(element.toString() + "\n"); } entity.setJsons(sb.toString()); entity.setRequestUrl(ServletUtil.getRequest().getServletPath()); entity.setRequestMethod(ServletUtil.getRequest().getMethod()); entity.setType(4); entity.setUserId(userInfo.getUserId()); entity.setIpAddress(IpUtil.getIpAddr()); entity.setCreatorTime(new Date()); entity.setPlatForm(ServletUtil.getUserAgent()); if (configValueUtil.isMultiTenancy() && StringUtil.isEmpty(DataSourceContextHolder.getDatasourceId())) { log.error("请求异常, 无登陆租户:" + ReflectionUtil.toString(entity), e); } else { logService.save(entity); } }catch (Exception g){ log.error(g.getMessage()); }finally { UserProvider.clearLocalUser(); TenantProvider.clearBaseSystemIfo(); DataSourceContextHolder.clearDatasourceType(); NotTenantPluginHolder.clearNotSwitchFlag(); } } /** * 覆盖默认的JSON响应 */ @Override @RequestMapping public ResponseEntity> error(HttpServletRequest request) { HttpStatus status = getStatus(request); if (status == HttpStatus.NOT_FOUND) { return new ResponseEntity<>(status); } return super.error(request); } }