parent
46fa7bf45e
commit
f0a9ba9243
@ -0,0 +1,37 @@
|
||||
package cn.teammodel.common;
|
||||
|
||||
public enum ErrorCode {
|
||||
|
||||
SUCCESS(0, "ok"),
|
||||
PARAMS_ERROR(40000, "请求参数错误"),
|
||||
NOT_LOGIN_ERROR(40100, "未登录"),
|
||||
NO_AUTH_ERROR(40101, "无权限"),
|
||||
NOT_FOUND_ERROR(40400, "请求数据不存在"),
|
||||
FORBIDDEN_ERROR(40300, "禁止访问"),
|
||||
SYSTEM_ERROR(50000, "系统内部异常"),
|
||||
OPERATION_ERROR(50001, "操作失败");
|
||||
|
||||
/**
|
||||
* 状态码
|
||||
*/
|
||||
private final int code;
|
||||
|
||||
/**
|
||||
* 信息
|
||||
*/
|
||||
private final String message;
|
||||
|
||||
ErrorCode(int code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
@ -1,37 +1,48 @@
|
||||
package cn.teammodel.common;
|
||||
|
||||
public class R {
|
||||
private Integer code;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class R<T> implements Serializable {
|
||||
|
||||
private int code;
|
||||
|
||||
private T data;
|
||||
|
||||
private String message;
|
||||
private String data;
|
||||
|
||||
public R(Integer code, String message, String data) {
|
||||
public R(int code, T data, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
this.data = data;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
public R(int code, T data) {
|
||||
this(code, data, "");
|
||||
}
|
||||
|
||||
public void setCode(Integer code) {
|
||||
this.code = code;
|
||||
public R(ErrorCode errorCode) {
|
||||
this(errorCode.getCode(), null, errorCode.getMessage());
|
||||
}
|
||||
public R(ErrorCode errorCode, T data) {
|
||||
this(errorCode.getCode(), data, errorCode.getMessage());
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
public static <T> R<T> success(T data) {
|
||||
return new R<>(ErrorCode.SUCCESS, data);
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
public static <T> R<T> error(String msg) {
|
||||
return new R<>(ErrorCode.SYSTEM_ERROR);
|
||||
}
|
||||
|
||||
public String getData() {
|
||||
return data;
|
||||
public static <T> R<T> error(Integer code, String msg) {
|
||||
return new R<>(code, null, msg);
|
||||
}
|
||||
|
||||
public void setData(String data) {
|
||||
this.data = data;
|
||||
public static <T> R<T> error(ErrorCode errorCode) {
|
||||
return new R<>(errorCode);
|
||||
}
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
package cn.teammodel.config.exception;
|
||||
|
||||
import cn.teammodel.common.R;
|
||||
import cn.teammodel.manager.NotificationService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.MissingPathVariableException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
/**
|
||||
* 全局异常处理器
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@RestControllerAdvice
|
||||
@Slf4j
|
||||
public class GlobalExceptionHandler {
|
||||
|
||||
@Resource
|
||||
private NotificationService notificationService;
|
||||
/**
|
||||
* 业务异常
|
||||
*/
|
||||
@ExceptionHandler(ServiceException.class)
|
||||
public R<?> handleServiceException(ServiceException e, HttpServletRequest request)
|
||||
{
|
||||
log.error(e.getMessage(), e);
|
||||
Integer code = e.getCode();
|
||||
return ObjectUtils.isNotEmpty(code) ? R.error(code, e.getMessage()) : R.error(e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求路径中缺少必需的路径变量
|
||||
*/
|
||||
@ExceptionHandler(MissingPathVariableException.class)
|
||||
public R<?> handleMissingPathVariableException(MissingPathVariableException e, HttpServletRequest request)
|
||||
{
|
||||
String requestURI = request.getRequestURI();
|
||||
log.error("请求路径中缺少必需的路径变量'{}',发生系统异常.", requestURI, e);
|
||||
return R.error(String.format("请求路径中缺少必需的路径变量[%s]", e.getVariableName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求参数类型不匹配
|
||||
*/
|
||||
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
|
||||
public R<?> handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e, HttpServletRequest request)
|
||||
{
|
||||
String requestURI = request.getRequestURI();
|
||||
log.error("请求参数类型不匹配'{}',发生系统异常.", requestURI, e);
|
||||
return R.error(String.format("请求参数类型不匹配,参数[%s]要求类型为:'%s',但输入值为:'%s'", e.getName(), e.getRequiredType().getName(), e.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 拦截未知的运行时异常
|
||||
*/
|
||||
@ExceptionHandler(RuntimeException.class)
|
||||
public R<?> handleRuntimeException(RuntimeException e, HttpServletRequest request)
|
||||
{
|
||||
String requestURI = request.getRequestURI();
|
||||
log.error("请求地址'{}',发生未知异常.", requestURI, e);
|
||||
notificationService.send("RuntimeException 告警: " + e.getMessage());
|
||||
return R.error(e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 系统异常
|
||||
*/
|
||||
@ExceptionHandler(Exception.class)
|
||||
public R<?> handleException(Exception e, HttpServletRequest request)
|
||||
{
|
||||
String requestURI = request.getRequestURI();
|
||||
log.error("请求地址'{}',发生系统异常.", requestURI, e);
|
||||
|
||||
notificationService.send("Exception 告警: " + e.getMessage());
|
||||
return R.error(e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义验证异常
|
||||
*/
|
||||
@ExceptionHandler(BindException.class)
|
||||
public R<?> handleBindException(BindException e)
|
||||
{
|
||||
log.error(e.getMessage(), e);
|
||||
String message = e.getAllErrors().get(0).getDefaultMessage();
|
||||
return R.error(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义验证异常
|
||||
*/
|
||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e)
|
||||
{
|
||||
log.error(e.getMessage(), e);
|
||||
String message = Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage();
|
||||
return R.error(message);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package cn.teammodel.manager;
|
||||
|
||||
import com.dingtalk.api.DefaultDingTalkClient;
|
||||
import com.dingtalk.api.DingTalkClient;
|
||||
import com.dingtalk.api.request.OapiRobotSendRequest;
|
||||
import com.taobao.api.ApiException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 钉钉告警服务
|
||||
* @author winter
|
||||
* @create 2023-11-14 10:11
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class DingAlertNotifier implements NotificationService{
|
||||
private final DingTalkClient client;
|
||||
@Autowired
|
||||
public DingAlertNotifier(@Value("${ding.server-url}") String dingServerUrl) {
|
||||
this.client = new DefaultDingTalkClient(dingServerUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(String message) {
|
||||
OapiRobotSendRequest request = new OapiRobotSendRequest();
|
||||
// 文本消息
|
||||
request.setMsgtype("text");
|
||||
OapiRobotSendRequest.Text text = new OapiRobotSendRequest.Text();
|
||||
text.setContent(message);
|
||||
request.setText(text);
|
||||
// at 管理员提醒异常
|
||||
OapiRobotSendRequest.At atAll = new OapiRobotSendRequest.At();
|
||||
atAll.setIsAtAll(true);
|
||||
request.setAt(atAll);
|
||||
try {
|
||||
client.execute(request);
|
||||
} catch (ApiException e) {
|
||||
log.error("钉钉 robot 推送消息渠道异常: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package cn.teammodel.manager;
|
||||
|
||||
/**
|
||||
* 消息通知接口
|
||||
* @author winter
|
||||
* @create 2023-11-14 10:08
|
||||
*/
|
||||
public interface NotificationService {
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
* @author: winter
|
||||
* @date: 2023/11/14 10:09
|
||||
*/
|
||||
void send(String message);
|
||||
}
|
@ -1,13 +1,19 @@
|
||||
package cn.teammodel;
|
||||
|
||||
import cn.teammodel.manager.DingAlertNotifier;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class TeamModelExtensionApplicationTests {
|
||||
|
||||
@Autowired
|
||||
private DingAlertNotifier notifier;
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
notifier.send("告警: 测试消息推送封装模块");
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in new issue