登录存redis中保存50分钟
@Autowired
private RedisTemplate<String, Object> template;
ValueOperations<String, Object> redisString = template.opsForValue();
redisString.set("token:" + uuids, JSON.toJSONString(sysUser), 60 * 50, TimeUnit.SECONDS);//token有效期50分钟
拦截器
package com.xiaoq.store.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
/**
* @author locken
* @date 2022-08-23 20:51
* @Description: -TOOD
*/
@Component
public class WebConfig extends WebMvcConfigurationSupport {
@Autowired
private MyInterceptorConfig myInterceptorConfig;
/**
* 添加接口请求拦截器 排除用户接口不用验证
* @param registry
*/
@Override
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(myInterceptorConfig)
.addPathPatterns("/**")
// .excludePathPatterns("/user/login");
.excludePathPatterns("/sys/login","/captchaImage")
.excludePathPatterns("/doc.html") //不需要拦截的地
.excludePathPatterns("/swagger-resources/**")
.excludePathPatterns("/webjars/**")
.excludePathPatterns("/v2/**")
.excludePathPatterns("/favicon.ico")
.excludePathPatterns("/swagger-ui.html/**");
}
/*
* @param registry
* @return void
* @introduction: 跨域支持
* @date 2021/5/19 21:44
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOriginPatterns("*")
.allowCredentials(true)
.allowedMethods("GET", "POST", "DELETE", "PUT", "PATCH", "OPTIONS", "HEAD")
.maxAge(3600 * 24);
}
/**
* 发现如果继承了WebMvcConfigurationSupport,则在yml中配置的相关内容会失效。 需要重新指定静态资源
*
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations(
"classpath:/static/");
registry.addResourceHandler("swagger-ui.html").addResourceLocations(
"classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations(
"classpath:/META-INF/resources/webjars/");
registry.addResourceHandler("doc.html").addResourceLocations(
"classpath:/META-INF/resources/");
super.addResourceHandlers(registry);
}
}
package com.xiaoq.store.config;
import io.swagger.models.HttpMethod;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
/**
* @author locken
* @date 2022-08-23 20:38
* @Description: -TOOD
*/
@Configuration
@Component
@Slf4j
public class MyInterceptorConfig implements HandlerInterceptor {
/**
* 添加接口请求拦截器
* @param request
* @param resp
* @param handler
* @return
* @throws Exception
*/
public boolean preHandle(HttpServletRequest request, HttpServletResponse resp, Object handler) throws Exception {
//打印请求内容
log.info("==============preHandle======start====================");
log.info("IP :" + request.getRemoteAddr());
log.info("URL :" + request.getRequestURL().toString());
log.info("HTTP Method :" + request.getMethod());
log.info("===============preHandle======End=====================");
if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) {
log.info("OPTIONS请求,放行");
return true;
}
log.info("------------ MyInterceptorConfig...................");
String token = request.getHeader("token");
log.info("=============== MyInterceptorConfig token : {}", token);
if (StringUtils.isBlank(token) ) {
log.info("=============== 请求拦截 : {}", token);
return false;
}
return true;
}
}
登录
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
@Autowired
private RedisTemplate<String, Object> template;
@ApiOperation("登录")
@PostMapping(value = "/login")
@OperLog(operModul = "后台系统-登录", operDesc = "登录")
public Result loginAdminUser(@RequestParam String username, @RequestParam String password, @RequestParam(required = false) String code, @RequestParam(required = false) String uuid) {
validateCaptcha(code, uuid);
Result<JSONObject> result = new Result<JSONObject>();
SysUser sysUser = sysUserService.getBaseMapper().selectOne(new QueryWrapper<SysUser>().eq("username", username));
if (ObjectUtil.isNotNull(sysUser)) {
String decrypt = PasswordUtil.decrypt(sysUser.getPassword(), sysUser.getUsername(), sysUser.getSalt());
if (decrypt.equals(password)) {
JSONObject obj = new JSONObject();
//获取验证码并将之放入到redis中,一分钟后失效
String uuids = IdUtils.getUUID();
ValueOperations<String, Object> redisString = template.opsForValue();
redisString.set("token:" + uuids, JSON.toJSONString(sysUser), 60 * 50, TimeUnit.SECONDS);//token有效期50分钟
obj.put("token", uuids);
obj.put("userInfo", sysUser);
result.setData(obj);
result.setCode(200);
result.setMsg("登录成功");
return result;
} else {
return result.setMsg("用户密码错误").setCode(400);
}
} else {
return result.setMsg("当前用户不存在").setCode(400);
}
}
实体类UserToken
package com.xiaoq.store.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(value = "用户token")
public class UserToken {
@ApiModelProperty(value = "名称")
private String username;
@ApiModelProperty(value = "密码")
private String password;
}
退出登录
@Autowired
private RedisTemplate<String, Object> template;
/**
* 退出登录
*
* @param request
* @param response
* @return
*/
@ApiOperation("退出登录")
@OperLog(operModul = "后台系统-退出登录", operDesc = "退出登录")
@PostMapping(value = "/logout")
public Result<Object> logout(HttpServletRequest request, HttpServletResponse response) throws Exception {
//用户退出逻辑
String token = request.getHeader("token");
if (oConvertUtils.isEmpty(token)) {
return Result.fail("退出登录失败!");
}
UserToken userToken = TokenFactory.validateToken(request);
log.info(" 用户名: " + userToken.getUsername() + ",退出成功! ");
//清空用户登录Token缓存
template.delete("token:" + token);
return Result.succeed("退出登录成功!");
}
每一个请求都要加上@OperLog注解
@ApiImplicitParams({@ApiImplicitParam(name = "email",value = "邮箱")})
@ApiOperation("欢迎语 邀请二维码")
@PostMapping(value = "welcome")
@OperLog(operModul = "后台系统-欢迎语",operDesc = "欢迎语")
public Result<Users> welcome(@RequestParam String email) {
}
启动类上加入 @MapperScan("com.xiaoq.store.mapper")
更换成自己的mapper路径
pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.4</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.54</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.5</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
数据库
DROP TABLE IF EXISTS `exception_log`;
CREATE TABLE `exception_log` (
`exc_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`exc_requ_param` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '请求参数',
`exc_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '异常名称',
`exc_message` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '异常信息',
`oper_user_id` int(11) NULL DEFAULT NULL COMMENT '操作员ID',
`oper_user_name` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '操作员姓名',
`oper_method` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '请求方法',
`base_path` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '根路径',
`oper_url` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '请求URL',
`oper_ip` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '请求IP',
`oper_ver` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '请求版本号',
`oper_create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`exc_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 17 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci COMMENT = '异常日志表' ROW_FORMAT = DYNAMIC;
SET FOREIGN_KEY_CHECKS = 1;
DROP TABLE IF EXISTS `operation_log`;
CREATE TABLE `operation_log` (
`oper_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`oper_modul` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '功能模块',
`oper_type` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '操作类型',
`oper_desc` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '操作描述',
`oper_requ_param` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '请求参数',
`oper_resp_param` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '返回参数',
`oper_user_id` int(11) NULL DEFAULT NULL COMMENT '操作员ID',
`oper_user_name` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '操作员名称',
`oper_method` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '操作方法',
`base_path` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '根路径',
`oper_url` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '请求Url',
`oper_ip` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '请求IP',
`oper_ver` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '操作版本号',
`oper_create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '操作时间',
PRIMARY KEY (`oper_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 24 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci COMMENT = '操作日志表' ROW_FORMAT = DYNAMIC;
SET FOREIGN_KEY_CHECKS = 1;
ExceptionLog
package com.xiaoq.galaxy.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("exception_log")
public class ExceptionLog extends Model<ExceptionLog> {
@TableId(value = "exc_id", type = IdType.AUTO)
private Integer excId;
@ApiModelProperty("请求参数")
private String excRequParam;
@ApiModelProperty("异常名称")
private String excName;
@ApiModelProperty("异常信息")
private String excMessage;
@ApiModelProperty("操作员ID")
private Integer operUserId;
@ApiModelProperty("操作员姓名")
private String operUserName;
@ApiModelProperty("请求方法")
private String operMethod;
@ApiModelProperty("请求URL")
private String operUrl;
@ApiModelProperty("请求IP")
private String operIp;
@ApiModelProperty("请求版本号")
private String operVer;
@ApiModelProperty("创建时间")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Date operCreateTime;
/**
* 根路径
*/
@ApiModelProperty("根路径")
private String basePath;
}
OperationLog
package com.xiaoq.galaxy.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
* 正常操作日志
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("operation_log")
public class OperationLog extends Model<OperationLog> {
@TableId(value = "oper_id", type = IdType.AUTO)
private Integer operId;
//功能模块
@ApiModelProperty("功能模块")
private String operModul;
//操作类型
@ApiModelProperty("操作类型")
private String operType;
//操作描述
@ApiModelProperty("操作描述")
private String operDesc;
//请求参数
@ApiModelProperty("请求参数")
private String operRequParam;
//返回参数
@ApiModelProperty("返回参数")
private String operRespParam;
//操作员ID
@ApiModelProperty("操作员ID")
private Integer operUserId;
//操作员名称
@ApiModelProperty("操作员名称")
private String operUserName;
//操作方法
@ApiModelProperty("操作方法")
private String operMethod;
//根路径
@ApiModelProperty("根路径")
private String basePath;
//请求Url
@ApiModelProperty("请求Url")
private String operUrl;
//请求Url
@ApiModelProperty("请求Url")
private String operIp;
//操作版本号
@ApiModelProperty("操作版本号")
private String operVer;
@ApiModelProperty("操作时间")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Date operCreateTime;
}
HttpUtils
package com.luck.backstage.tests;
import org.apache.commons.lang3.StringUtils;
import javax.servlet.http.HttpServletRequest;
public class HttpUtils {
/**
* 获取用户真实IP地址,不使用request.getRemoteAddr();的原因是有可能用户使用了代理软件方式避免真实IP地址,
*
* 可是,如果通过了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP值,究竟哪个才是真正的用户端的真实IP呢?
* 答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。
*
* 如:X-Forwarded-For:192.168.1.110, 192.168.1.120, 192.168.1.130,
* 192.168.1.100
*
* 用户真实IP为: 192.168.1.110
*
* @param request
* @return
*/
public static String getIpAddress(HttpServletRequest request) {
String Xip = request.getHeader("X-Real-IP");
String XFor = request.getHeader("X-Forwarded-For");
//多次反向代理后会有多个ip值,第一个ip才是真实ip
if (StringUtils.isNotEmpty(XFor) && !"unKnown".equalsIgnoreCase(XFor)) {
int index = XFor.indexOf(",");
if (index != -1) {
return "0:0:0:0:0:0:0:1".equals(XFor.substring(0, index)) ? "127.0.0.1" : XFor.substring(0, index);
} else {
return "0:0:0:0:0:0:0:1".equals(XFor) ? "127.0.0.1" : XFor;
}
}
XFor = Xip;
if (StringUtils.isNotEmpty(XFor) && !"unKnown".equalsIgnoreCase(XFor))
return "0:0:0:0:0:0:0:1".equals(XFor) ? "127.0.0.1" : XFor;
if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor))
XFor = request.getHeader("Proxy-Client-IP");
if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor))
XFor = request.getHeader("WL-Proxy-Client-IP");
if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor))
XFor = request.getHeader("HTTP_CLIENT_IP");
if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor))
XFor = request.getHeader("HTTP_X_FORWARDED_FOR");
if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor))
XFor = request.getRemoteAddr();
return "0:0:0:0:0:0:0:1".equals(XFor) ? "127.0.0.1" : XFor;
}
}
OperLog
package com.luck.backstage.tests;
import java.lang.annotation.*;
/**
* AOP日志切入
*/
@Target(ElementType.METHOD) //注解放置的目标位置,METHOD是可注解在方法级别上
@Retention(RetentionPolicy.RUNTIME) //注解在哪个阶段执行
@Documented
public @interface OperLog {
String operModul() default ""; // 操作模块
String operType() default ""; // 操作类型
String operDesc() default ""; // 操作说明
}
ExceptionLogDao
package com.luck.backstage.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.luck.backstage.entity.Days;
import com.luck.backstage.tests.ExceptionLog;
public interface ExceptionLogDao extends BaseMapper<ExceptionLog> {
}
OperationLogDao
package com.luck.backstage.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.luck.backstage.entity.SysUser;
import com.luck.backstage.tests.OperationLog;
public interface OperationLogDao extends BaseMapper<OperationLog> {
}
ExceptionLogService
package com.luck.backstage.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.luck.backstage.test.SysLog;
import com.luck.backstage.tests.ExceptionLog;
public interface ExceptionLogService extends IService<ExceptionLog> {
}
OperationLogService
package com.luck.backstage.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.luck.backstage.entity.SysUser;
import com.luck.backstage.tests.OperationLog;
import org.springframework.stereotype.Service;
@Service
public interface OperationLogService extends IService<OperationLog> {
}
ExceptionLogServiceImpl
package com.luck.backstage.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.luck.backstage.dao.ExceptionLogDao;
import com.luck.backstage.dao.LogRepository;
import com.luck.backstage.service.ExceptionLogService;
import com.luck.backstage.service.LogService;
import com.luck.backstage.test.SysLog;
import com.luck.backstage.tests.ExceptionLog;
import org.springframework.stereotype.Service;
@Service
public class ExceptionLogServiceImpl extends ServiceImpl<ExceptionLogDao, ExceptionLog> implements ExceptionLogService {
}
OperationLogServiceImpl
package com.luck.backstage.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.luck.backstage.dao.OperationLogDao;
import com.luck.backstage.dao.SysUserDao;
import com.luck.backstage.entity.SysUser;
import com.luck.backstage.service.OperationLogService;
import com.luck.backstage.service.SysUserService;
import com.luck.backstage.tests.OperationLog;
import org.springframework.stereotype.Service;
@Service
public class OperationLogServiceImpl extends ServiceImpl<OperationLogDao, OperationLog> implements OperationLogService {
}
OperLogAspect
更换 @Pointcut("@annotation(com.qhzx.mad.backstage.config.OperLog)")
@Pointcut("execution(* com.qhzx.mad.backstage.controller..*.*(..))")
package com.xiaoq.store.config;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.PropertyFilter;
import com.xiaoq.store.entity.ExceptionLog;
import com.xiaoq.store.entity.OperationLog;
import com.xiaoq.store.entity.UserToken;
import com.xiaoq.store.service.ExceptionLogService;
import com.xiaoq.store.service.OperationLogService;
import com.xiaoq.store.util.HttpUtils;
import com.xiaoq.store.util.OperLog;
import com.xiaoq.store.util.TokenFactory;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.multipart.MultipartFile;
/**
* 登录自定义表单其他参数
*/
@Aspect
@Component
public class OperLogAspect {
@Autowired
private Environment env;
@Autowired
private ExceptionLogService exceptionLogService;
@Autowired
private OperationLogService operationLogService;
/**
* 设置操作日志切入点 记录操作日志 在注解的位置切入代码
*/
@Pointcut("@annotation(com.xiaoq.store.util.OperLog)")
public void operLogPoinCut() {
}
/**
* 设置操作异常切入点记录异常日志 扫描所有controller包下操作
*/
@Pointcut("execution(* com.xiaoq.store.web.controller..*.*(..))")
public void operExceptionLogPoinCut() {
}
/**
* 正常返回通知,拦截用户操作日志,连接点正常执行完成后执行, 如果连接点抛出异常,则不会执行
*
* @param joinPoint 切入点
* @param keys 返回结果
*/
@AfterReturning(value = "operLogPoinCut()", returning = "keys")
public void saveOperLog(JoinPoint joinPoint, Object keys) throws Exception {
// 获取RequestAttributes
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
HttpServletRequest request = (HttpServletRequest) requestAttributes
.resolveReference(RequestAttributes.REFERENCE_REQUEST);
OperationLog operlog = new OperationLog();
// 从切面织入点处通过反射机制获取织入点处的方法
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();// 获取切入点所在的方法
OperLog opLog = method.getAnnotation(OperLog.class);//获取操作
String operDesc = null;
if (opLog !=null){
String operModul = opLog.operModul();
String operType = opLog.operType();
operDesc = opLog.operDesc();
operlog.setOperModul(operModul); // 操作模块
operlog.setOperType(operType); // 操作类型
operlog.setOperDesc(operDesc); // 操作描述
}
String urlStr = request.getRequestURL().toString();
// 获取请求的类名
String className = joinPoint.getTarget().getClass().getName();
String methodName = method.getName();// 获取请求的方法名
methodName = className + "." + methodName;
operlog.setOperMethod(methodName); // 请求方法
operlog.setOperRequParam(getReqestParams(request,joinPoint));
operlog.setOperRespParam(JSON.toJSONString(keys));
// operlog.setOperUserId(user.getSysId());
if (!Objects.equals(operDesc, "登录") && !Objects.equals(operDesc, "退出登录")){
UserToken userToken = TokenFactory.validateToken(request);
operlog.setOperUserName(userToken.getUsername());
}
operlog.setOperIp(HttpUtils.getIpAddress(request));
operlog.setOperUrl(request.getRequestURI());
operlog.setOperVer(env.getProperty("platform.operVer"));
operlog.setBasePath(StrUtil.removeSuffix(urlStr, URLUtil.url(urlStr).getPath()));
operationLogService.save(operlog);
}
/**
* 异常返回通知,用于拦截异常日志信息 连接点抛出异常后执行
*
* @param joinPoint 切入点
* @param e 异常信息
*/
@AfterThrowing(pointcut = "operExceptionLogPoinCut()", throwing = "e")
public void saveExceptionLog(JoinPoint joinPoint, Throwable e) {
// 获取RequestAttributes
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
// 从获取RequestAttributes中获取HttpServletRequest的信息
HttpServletRequest request = (HttpServletRequest) requestAttributes
.resolveReference(RequestAttributes.REFERENCE_REQUEST);
ExceptionLog excepLog = new ExceptionLog();
try {
// 从切面织入点处通过反射机制获取织入点处的方法
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
// 获取切入点所在的方法
Method method = signature.getMethod();
String urlStr = request.getRequestURL().toString();
String className = joinPoint.getTarget().getClass().getName();
String methodName = method.getName();
methodName = className + "." + methodName;
// Map rtnMap = converMap(request.getParameterMap());
// String params = JSON.toJSONString(rtnMap);
excepLog.setExcRequParam(getReqestParams(request,joinPoint));
// excepLog.setExcRequParam(params);
excepLog.setOperMethod(methodName);
excepLog.setExcName(e.getClass().getName());
excepLog.setExcMessage(stackTraceToString(e.getClass().getName(), e.getMessage(), e.getStackTrace()));
// SystemUser user = SesionUtils.getSysUserSession();
// excepLog.setOperUserId(user.getSysId());
// excepLog.setOperUserName(user.getUsername());
excepLog.setOperUrl(request.getRequestURI());
excepLog.setOperIp(HttpUtils.getIpAddress(request));
excepLog.setOperVer(env.getProperty("platform.operVer"));
excepLog.setBasePath(StrUtil.removeSuffix(urlStr, URLUtil.url(urlStr).getPath()));
exceptionLogService.save(excepLog);
} catch (Exception e2) {
e2.printStackTrace();
}
}
/**
* @Description: 获取请求参数
* @author: scott
* @date: 2020/4/16 0:10
* @param request: request
* @param joinPoint: joinPoint
* @Return: java.lang.String
*/
private String getReqestParams(HttpServletRequest request, JoinPoint joinPoint) {
String httpMethod = request.getMethod();
String params = "";
if ("POST".equals(httpMethod) || "PUT".equals(httpMethod) || "PATCH".equals(httpMethod)) {
Object[] paramsArray = joinPoint.getArgs();
// java.lang.IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false)
// https://my.oschina.net/mengzhang6/blog/2395893
Object[] arguments = new Object[paramsArray.length];
for (int i = 0; i < paramsArray.length; i++) {
if (paramsArray[i] instanceof BindingResult || paramsArray[i] instanceof ServletRequest || paramsArray[i] instanceof ServletResponse || paramsArray[i] instanceof MultipartFile) {
//ServletRequest不能序列化,从入参里排除,否则报异常:java.lang.IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false)
//ServletResponse不能序列化 从入参里排除,否则报异常:java.lang.IllegalStateException: getOutputStream() has already been called for this response
continue;
}
arguments[i] = paramsArray[i];
}
//update-begin-author:taoyan date:20200724 for:日志数据太长的直接过滤掉
PropertyFilter profilter = new PropertyFilter() {
@Override
public boolean apply(Object o, String name, Object value) {
if(value!=null && value.toString().length()>500){
return false;
}
return true;
}
};
params = JSONObject.toJSONString(arguments, profilter);
//update-end-author:taoyan date:20200724 for:日志数据太长的直接过滤掉
} else {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
// 请求的方法参数值
Object[] args = joinPoint.getArgs();
// 请求的方法参数名称
LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
String[] paramNames = u.getParameterNames(method);
if (args != null && paramNames != null) {
for (int i = 0; i < args.length; i++) {
params += " " + paramNames[i] + ": " + args[i];
}
}
}
return params;
}
/**
* 转换request 请求参数
*
* @param paramMap request获取的参数数组
*/
public Map<String, String> converMap(Map<String, String[]> paramMap) {
Map<String, String> rtnMap = new HashMap<String, String>();
for(String key : paramMap.keySet()) {
rtnMap.put(key, paramMap.get(key)[0]);
}
return rtnMap;
}
/**
* 转换异常信息为字符串
*
* @param exceptionName 异常名称
* @param exceptionMessage 异常信息
* @param elements 堆栈信息
*/
public String stackTraceToString(String exceptionName, String exceptionMessage, StackTraceElement[] elements) {
StringBuffer strbuff = new StringBuffer();
for (StackTraceElement stet : elements) {
strbuff.append(stet + "\n");
}
String message = exceptionName + ":" + exceptionMessage + "\n\t" + strbuff.toString();
return message;
}
}
ExceptionLogController
package com.xiaoq.store.web.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaoq.store.entity.ExceptionLog;
import com.xiaoq.store.mapper.ExceptionLogDao;
import com.xiaoq.store.service.ExceptionLogService;
import com.xiaoq.store.util.OperLog;
import com.xiaoq.store.util.Result;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
* 异常日志
*/
@RestController
@RequestMapping("/ExceptionLog")
@CrossOrigin
@Slf4j
public class ExceptionLogController {
@Resource
private ExceptionLogDao exceptionLogDao;
//异常日志分页查询所有数据
@ApiOperation("异常日志分页查询所有数据")
@GetMapping(value = "/selectPage")
@OperLog(operModul = "后台系统-异常日志分页查询所有数据",operDesc = "异常日志分页查询所有数据")
public Result<IPage<ExceptionLog>> selectPage(
@RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum,
@RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize) {
return Result.succeed(exceptionLogDao.selectPage(new Page<>(pageNum, pageSize), new QueryWrapper<>()));
}
//新增异常日志
@ApiOperation("新增异常日志")
@PostMapping(value = "addSave")
@OperLog(operModul = "后台系统-新增异常日志",operDesc = "新增异常日志")
public Result<Integer> addSave(@RequestBody ExceptionLog exceptionLog) {
return Result.succeed(exceptionLogDao.insert(exceptionLog));
}
//修改异常日志
@ApiOperation("修改异常日志")
@PostMapping(value = "update")
@OperLog(operModul = "后台系统-修改异常日志",operDesc = "修改异常日志")
public Result<Integer> update(@RequestBody ExceptionLog exceptionLog) {
return Result.succeed(exceptionLogDao.updateById(exceptionLog));
}
//删除异常日志
@ApiOperation("删除异常日志")
@PostMapping(value = "delete")
@OperLog(operModul = "后台系统-删除异常日志",operDesc = "删除异常日志")
public Result<Integer> delete(@RequestParam String id) {
return Result.succeed(exceptionLogDao.deleteById(id));
}
}
OperationLogController
package com.xiaoq.store.web.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaoq.store.entity.OperationLog;
import com.xiaoq.store.mapper.OperationLogDao;
import com.xiaoq.store.util.OperLog;
import com.xiaoq.store.util.Result;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
* 正常日志
*/
@RestController
@RequestMapping("/OperationLog")
@CrossOrigin
@Slf4j
public class OperationLogController {
@Resource
private OperationLogDao operationLogDao;
//操作日志查询所有数据
@ApiOperation("操作日志查询所有数据")
@GetMapping(value = "/selectPage")
@OperLog(operModul = "后台系统-操作日志查询所有数据",operDesc = "操作日志查询所有数据")
public Result<IPage<OperationLog>> selectPage(
@RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum,
@RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize) {
return Result.succeed(operationLogDao.selectPage(new Page<>(pageNum, pageSize), new QueryWrapper<>()));
}
//新增操作日志
@ApiOperation("新增操作日志")
@PostMapping(value = "addSave")
@OperLog(operModul = "后台系统-新增操作日志",operDesc = "新增操作日志")
public Result<Integer> addSave(@RequestBody OperationLog operationLog) {
return Result.succeed(operationLogDao.insert(operationLog));
}
//修改操作日志
@ApiOperation("修改操作日志")
@PostMapping(value = "update")
@OperLog(operModul = "后台系统-修改操作日志",operDesc = "修改操作日志")
public Result<Integer> update(@RequestBody OperationLog operationLog) {
return Result.succeed(operationLogDao.updateById(operationLog));
}
//删除操作日志
@ApiOperation("删除操作日志")
@PostMapping(value = "delete")
@OperLog(operModul = "后台系统-删除操作日志",operDesc = "删除操作日志")
public Result<Integer> delete(@RequestParam String id) {
return Result.succeed(operationLogDao.deleteById(id));
}
}
TokenFactory
package com.xiaoq.store.util;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.xiaoq.store.entity.UserToken;
import com.xiaoq.store.exception.ComFoundException;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import static com.xiaoq.store.constant.enums.CommonEnum.FAILED_RESPONSE;
import static com.xiaoq.store.constant.enums.CommonEnum.SUCCESS_RESPONSE;
@Component
public class TokenFactory {
private static RedisTemplate redisTemplate; //存储对象
@Autowired
public void setRedisTemplate(RedisTemplate redisTemplate) {
TokenFactory.redisTemplate = redisTemplate;
}
private static UserToken get(String key) {
Object token = redisTemplate.opsForValue().get("token:"+key);
return token == null ? null : JSON.parseObject(token.toString(), UserToken.class);
}
private static List<UserToken> gets(String key) {
Object token = redisTemplate.opsForValue().get("token:"+key);
return token == null ? null : JSONArray.parseArray(token.toString(), UserToken.class);
}
public static UserToken validateToken(HttpServletRequest request) throws Exception {
String token = request.getHeader("token");
UserToken userToken = get(token);
Assert.notEmpty(token, "token不能为空!");
Assert.notNull(userToken, "token无效!");
return userToken;
}
//测试
public static List<UserToken> validateTokens(HttpServletRequest request) {
String token = request.getHeader("token");
Assert.notEmpty(token, "token不能为空!");
List<UserToken> userToken = gets(token);
Assert.notNull(userToken, "token无效!");
return userToken;
}
}
全局异常处理DefaultExceptionAdvice
package com.xiaoq.store.exception;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.xiaoq.store.StarcraftApplication;
import com.xiaoq.store.util.Result;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.NoHandlerFoundException;
import java.sql.SQLException;
import java.util.List;
@ControllerAdvice
@ResponseBody
public class DefaultExceptionAdvice {
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultExceptionAdvice.class);
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler({HttpMessageNotReadableException.class,})
public ResponseEntity handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
LOGGER.error("参数解析失败", e);
Response response = Response.failure(DefaultError.INVALID_PARAMETER);
response.setResult(e.getMessage());
return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
}
@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
@ExceptionHandler({HttpRequestMethodNotSupportedException.class})
public ResponseEntity handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
LOGGER.error("不支持当前请求方法", e);
Response response = Response.failure(DefaultError.METHOD_NOT_SUPPORTED);
response.setResult(e.getMessage());
return new ResponseEntity<>(response, HttpStatus.METHOD_NOT_ALLOWED);
}
@ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
@ExceptionHandler({HttpMediaTypeNotSupportedException.class})
public ResponseEntity handleHttpMediaTypeNotSupportedException(HttpMediaTypeNotSupportedException e) {
LOGGER.error("不支持当前媒体类型", e);
Response response = Response.failure(DefaultError.CONTENT_TYPE_NOT_SUPPORT);
response.setResult(e.getMessage());
return new ResponseEntity<>(response, HttpStatus.UNSUPPORTED_MEDIA_TYPE);
}
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler({SQLException.class})
public ResponseEntity handleSQLException(SQLException e) {
LOGGER.error("服务运行SQLException异常", e);
Response response = Response.failure(DefaultError.SQL_EXCEPTION);
response.setResult(e.getMessage());
return new ResponseEntity<>(response, HttpStatus.INTERNAL_SERVER_ERROR);
}
/**
* 所有异常统一处理
*
* @return ResponseEntity
*/
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(Exception.class)
public ResponseEntity handleException(Exception ex) {
LOGGER.error("未知异常", ex);
IError error;
String extMessage = null;
if (ex instanceof BindException) {
error = DefaultError.INVALID_PARAMETER;
List<ObjectError> errors = ((BindException) ex).getAllErrors();
if (errors.size() != 0) {
StringBuilder msg = new StringBuilder();
for (ObjectError objectError : errors) {
msg.append("Field error in object '").append(objectError.getObjectName()).append(" ");
if (objectError instanceof FieldError) {
msg.append("on field ").append(((FieldError) objectError).getField()).append(" ");
}
msg.append(objectError.getDefaultMessage()).append(" ");
}
extMessage = msg.toString();
}
} else if (ex instanceof MissingServletRequestParameterException) {
error = DefaultError.INVALID_PARAMETER;
extMessage = ex.getMessage();
} else if (ex instanceof HttpMediaTypeNotSupportedException) {
error = DefaultError.CONTENT_TYPE_NOT_SUPPORT;
extMessage = ex.getMessage();
} else if (ex instanceof HttpMessageNotReadableException) {
error = DefaultError.INVALID_PARAMETER;
extMessage = ex.getMessage();
} else if (ex instanceof MethodArgumentNotValidException) {
error = DefaultError.INVALID_PARAMETER;
final BindingResult result = ((MethodArgumentNotValidException) ex).getBindingResult();
if (result.hasErrors()) {
extMessage = result.getAllErrors().get(0).getDefaultMessage();
} else {
extMessage = ex.getMessage();
}
} else if (ex instanceof HttpRequestMethodNotSupportedException) {
error = DefaultError.METHOD_NOT_SUPPORTED;
extMessage = ex.getMessage();
} else if (ex instanceof NoHandlerFoundException) {
error = DefaultError.SERVICE_NOT_FOUND;
extMessage = ex.getMessage();
} else {
error = DefaultError.SYSTEM_INTERNAL_ERROR;
extMessage = ex.getMessage();
}
Response response = Response.failure(error);
response.setResult(extMessage);
return new ResponseEntity<>(response, HttpStatus.INTERNAL_SERVER_ERROR);
}
/**
* BusinessException 业务异常处理
*
* @return ResponseEntity
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(BusinessException.class)
public ResponseEntity handleException(BusinessException e) {
LOGGER.error("业务异常", e);
Response response = Response.failure(e.getError());
return new ResponseEntity<>(response, HttpStatus.OK);
}
@ExceptionHandler({BaseException.class})
public Result BaseExceptionHandler(BaseException e) {
// 从异常对象中拿到信息
String message = e.getDefaultMessage();
String code = e.getCode();
// 返回
return Result.succeed(Result.fail(Integer.parseInt(code),message),message);
}
@ExceptionHandler({ComFoundException.class})
public Result ComFoundExceptionHandler(ComFoundException e) {
// 从异常对象中拿到信息
String message = e.getMessage();
// 返回
return Result.succeed(Result.fail(400,message),message);
}
@ExceptionHandler({MybatisPlusException.class})
public Result MybatisPlusException(MybatisPlusException e) {
// 从异常对象中拿到信息
String message = e.getMessage();
// 返回
return Result.succeed(Result.fail(400,message),message);
}
}
Response
package com.xiaoq.store.exception;
import lombok.Data;
import java.io.Serializable;
/**
* 说明:统一 Rest 返回对象
*
* @author zhangwei
* @date 2017年11月18日23:45:05
*/
@Data
public class Response implements Serializable {
private static final long serialVersionUID = -5359531292427290394L;
private String errorCode;
private String errorMessage;
private String extMessage;
private Object result;
private Status status;
private Object data;
public Response() {
this.status = Status.SUCCEED;
}
public Response(IError error) {
this.errorCode = error.getErrorCode();
this.errorMessage = error.getErrorMessage();
this.status = Status.FAILED;
}
public static Response success() {
return new Response();
}
public static Response success(Object result) {
Response response = new Response();
response.setResult(result);
return response;
}
public static Response failure(String errorCode, String errorMessage) {
Response response = new Response();
response.errorCode = errorCode;
response.errorMessage = errorMessage;
response.status = Status.FAILED;
return response;
}
public static Response failure(IError error) {
Response response = new Response();
response.errorCode = error.getErrorCode();
response.errorMessage = error.getErrorMessage();
response.status = Status.FAILED;
return response;
}
public static Response failure(String message) {
Response response = new Response();
response.setErrorMessage(message);
response.status = Status.FAILED;
return response;
}
public static Response failure(String message, Object data) {
Response response = new Response();
response.setErrorMessage(message);
response.setData(data);
response.status = Status.FAILED;
return response;
}
public static Response warring(Object result) {
Response response = new Response();
response.setResult(result);
response.status = Status.WARRING;
return response;
}
public enum Status {
/**
* 状态
*/
SUCCEED,
WARRING,
FAILED;
Status() {
}
}
}
IError
package com.qhzx.exception;
/**
* 说明:
*
* @author zhangwei
* @version 2017/11/21 15:21.
*/
public interface IError {
/**
* 获取nameSpace
*
* @return nameSpace
*/
String getNameSpace();
/**
* 获取错误码
*
* @return 错误码
*/
String getErrorCode();
/**
* 获取错误信息
*
* @return 错误信息
*/
String getErrorMessage();
/**
* 设置错误信息
*
* @param errorMessage 错误信息
*/
void setErrorMessage(String errorMessage);
}
IError
package com.qhzx.exception;
/**
* 说明:
*
* @author zhangwei
* @version 2017/11/21 15:21.
*/
public interface IError {
/**
* 获取nameSpace
*
* @return nameSpace
*/
String getNameSpace();
/**
* 获取错误码
*
* @return 错误码
*/
String getErrorCode();
/**
* 获取错误信息
*
* @return 错误信息
*/
String getErrorMessage();
/**
* 设置错误信息
*
* @param errorMessage 错误信息
*/
void setErrorMessage(String errorMessage);
}
DefaultError
package com.qhzx.exception;
/**
* 说明:默认异常
*
* @author zhangwei
* @date 2017年11月18日23:45:26
*/
public enum DefaultError implements IError {
/**
* 系统内部错误
*/
SYSTEM_INTERNAL_ERROR("0000", "系统错误"),
/**
* 无效参数
*/
INVALID_PARAMETER("0001", "参数验证失败"),
/**
* 服务不存在
*/
SERVICE_NOT_FOUND("0002", "服务不存在"),
/**
* 参数不全
*/
PARAMETER_REQUIRED("0003", "参数不全"),
/**
* 参数过长
*/
PARAMETER_MAX_LENGTH("0004", "参数过长"),
/**
* 参数过短
*/
PARAMETER_MIN_LENGTH("0005", "参数过短"),
/**
* 认证失败
*/
AUTHENTICATION_ERROR("0006", "认证失败"),
/**
* 认证动作失败
*/
AUTHENTICATION_OPTION_ERROR("0007", "认证失败"),
/**
* 请求方法出错
*/
METHOD_NOT_SUPPORTED("0008", "请求方法出错"),
/**
* 不支持的content类型
*/
CONTENT_TYPE_NOT_SUPPORT("0009", "不支持的content类型"),
/**
* json格式化出错
*/
JSON_FORMAT_ERROR("0010", "json格式化出错"),
/**
* 远程调用出错
*/
CALL_REMOTE_ERROR("0011", "远程调用出错"),
/**
* 服务运行SQLException异常
*/
SQL_EXCEPTION("0012", "服务运行SQL异常"),
/**
* 客户端异常 给调用者 app,移动端调用
*/
CLIENT_EXCEPTION("0013", "客户端异常"),
/**
* 服务端异常, 微服务服务端产生的异常
*/
SERVER_EXCEPTION("0014", "服务端异常"),
/**
* 授权失败 禁止访问
*/
ACCESS_DENIED("0015", "没有访问权限"),
/**
* 演示环境 没有权限访问
*/
SHOW_AUTH_CONTROL("0016", "演示环境,没有权限访问"),
/**
* 业务异常
*/
BUSINESS_ERROR("0017", "业务异常"),
NO_USER("0018", "用户不存在");
private static final String NS = "SYS";
String errorCode;
String errorMessage;
DefaultError(String errorCode, String errorMessage) {
this.errorCode = errorCode;
this.errorMessage = errorMessage;
}
@Override
public String getNameSpace() {
return NS;
}
@Override
public String getErrorCode() {
return NS + "." + this.errorCode;
}
@Override
public String getErrorMessage() {
return this.errorMessage;
}
@Override
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
}
ComFoundException
package com.qhzx.exception;
/**
* 编写统一返回异常类
* @ClassName CaptchaException
* @Author Blue Email:[email protected]
* @Date 2022/9/13
*/
public class ComFoundException extends RuntimeException {
public ComFoundException() {
super();
}
public ComFoundException(String message) {
super(message);
}
public ComFoundException(String message, Throwable cause) {
super(message, cause);
}
public ComFoundException(Throwable cause) {
super(cause);
}
protected ComFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
BusinessException
package com.qhzx.exception;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
public class BusinessException extends BaseException {
private static final long serialVersionUID = 3076984003548588117L;
private IError error = DefaultError.BUSINESS_ERROR;
private String extMessage;
public BusinessException(String message) {
super(message);
this.error.setErrorMessage(message);
}
public BusinessException(String message, String extMessage) {
super(message + ":" + extMessage);
this.error.setErrorMessage(message);
this.extMessage = extMessage;
}
}
BaseException
package com.qhzx.exception;
import com.alibaba.druid.util.StringUtils;
/**
* 基本异常.
*/
class BaseException extends RuntimeException {
private static final long serialVersionUID = 1L;
/**
* 所属模块
*/
private String module;
/**
* 错误码
*/
private String code;
/**
* 错误码对应的参数
*/
private Object[] args;
/**
* 错误消息
*/
private String defaultMessage;
public BaseException(String module, String code, Object[] args, String defaultMessage) {
this.module = module;
this.code = code;
this.args = args;
this.defaultMessage = defaultMessage;
}
public BaseException(String module, String code, Object[] args) {
this(module, code, args, null);
}
public BaseException(String module, String defaultMessage) {
this(module, null, null, defaultMessage);
}
public BaseException(String code, Object[] args) {
this(null, code, args, null);
}
public BaseException(String defaultMessage) {
this(null, null, null, defaultMessage);
}
@Override
public String getMessage() {
String message = null;
if (!StringUtils.isEmpty(code)) {
message = "无";
}
if (message == null) {
message = defaultMessage;
}
return message;
}
public String getModule()
{
return module;
}
public String getCode()
{
return code;
}
public Object[] getArgs()
{
return args;
}
public String getDefaultMessage()
{
return defaultMessage;
}
}