fix: 调整项目路径
This commit is contained in:
52
src/main/java/mjkf/xinke/Application.java
Normal file
52
src/main/java/mjkf/xinke/Application.java
Normal file
@@ -0,0 +1,52 @@
|
||||
|
||||
package mjkf.xinke;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.Banner;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
|
||||
|
||||
/**
|
||||
* SpringBoot方式启动类
|
||||
*
|
||||
*
|
||||
* @date 2021/12/18 16:57
|
||||
*/
|
||||
@Slf4j
|
||||
@EnableSwagger2WebMvc
|
||||
@RestController
|
||||
@SpringBootApplication
|
||||
public class Application {
|
||||
|
||||
/* 解决druid 日志报错:discard long time none received connection:xxx */
|
||||
static {
|
||||
System.setProperty("druid.mysql.usePingMethod","false");
|
||||
}
|
||||
|
||||
/**
|
||||
* 主启动函数
|
||||
*
|
||||
*
|
||||
* @date 2022/7/30 21:42
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
SpringApplication springApplication = new SpringApplication(Application.class);
|
||||
springApplication.setBannerMode(Banner.Mode.OFF);
|
||||
springApplication.run(args);
|
||||
log.info(">>> {}", Application.class.getSimpleName().toUpperCase() + " STARTING SUCCESS");
|
||||
}
|
||||
|
||||
/**
|
||||
* 首页
|
||||
*
|
||||
*
|
||||
* @date 2022/7/8 14:22
|
||||
**/
|
||||
@GetMapping("/")
|
||||
public String index() {
|
||||
return "WELCOME";
|
||||
}
|
||||
}
|
65
src/main/java/mjkf/xinke/core/config/DruidConfigure.java
Normal file
65
src/main/java/mjkf/xinke/core/config/DruidConfigure.java
Normal file
@@ -0,0 +1,65 @@
|
||||
|
||||
package mjkf.xinke.core.config;
|
||||
|
||||
import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties;
|
||||
import com.alibaba.druid.util.Utils;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import javax.servlet.*;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* druid配置
|
||||
*
|
||||
* @author diantu
|
||||
* @date 2023/06/30
|
||||
**/
|
||||
@Configuration
|
||||
public class DruidConfigure {
|
||||
|
||||
/**
|
||||
* 去除druid监控页面广告
|
||||
*/
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@Bean
|
||||
public FilterRegistrationBean removeDruidAdFilterRegistrationBean(DruidStatProperties properties)
|
||||
{
|
||||
// 获取web监控页面的参数
|
||||
DruidStatProperties.StatViewServlet config = properties.getStatViewServlet();
|
||||
// 提取common.js的配置路径
|
||||
String pattern = config.getUrlPattern() != null ? config.getUrlPattern() : "/druid/*";
|
||||
String commonJsPattern = pattern.replaceAll("\\*", "js/common.js");
|
||||
final String filePath = "support/http/resources/js/common.js";
|
||||
// 创建filter进行过滤
|
||||
Filter filter = new Filter()
|
||||
{
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException
|
||||
{
|
||||
}
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException
|
||||
{
|
||||
chain.doFilter(request, response);
|
||||
// 重置缓冲区,响应头不会被重置
|
||||
response.resetBuffer();
|
||||
// 获取common.js
|
||||
String text = Utils.readFromResource(filePath);
|
||||
// 正则替换banner, 除去底部的广告信息
|
||||
text = text.replaceAll("<a.*?banner\"></a><br/>", "");
|
||||
text = text.replaceAll("powered.*?shrek.wang</a>", "");
|
||||
response.getWriter().write(text);
|
||||
}
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
}
|
||||
};
|
||||
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
|
||||
registrationBean.setFilter(filter);
|
||||
registrationBean.addUrlPatterns(commonJsPattern);
|
||||
return registrationBean;
|
||||
}
|
||||
}
|
618
src/main/java/mjkf/xinke/core/config/GlobalConfigure.java
Normal file
618
src/main/java/mjkf/xinke/core/config/GlobalConfigure.java
Normal file
@@ -0,0 +1,618 @@
|
||||
|
||||
package mjkf.xinke.core.config;
|
||||
|
||||
import cn.dev33.satoken.context.SaHolder;
|
||||
import cn.dev33.satoken.context.model.SaResponse;
|
||||
import cn.dev33.satoken.filter.SaServletFilter;
|
||||
import cn.dev33.satoken.router.SaHttpMethod;
|
||||
import cn.dev33.satoken.router.SaRouter;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.core.util.EnumUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.http.ContentType;
|
||||
import cn.hutool.http.Header;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.apache.ibatis.mapping.DatabaseIdProvider;
|
||||
import org.apache.ibatis.reflection.MetaObject;
|
||||
import org.apache.ibatis.reflection.ReflectionException;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
import org.springframework.jdbc.support.JdbcUtils;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import mjkf.xinke.auth.core.util.StpClientUtil;
|
||||
import mjkf.xinke.common.annotation.CommonNoRepeat;
|
||||
import mjkf.xinke.common.annotation.CommonWrapper;
|
||||
import mjkf.xinke.common.cache.CommonCacheOperator;
|
||||
import mjkf.xinke.common.enums.CommonDeleteFlagEnum;
|
||||
import mjkf.xinke.common.exception.CommonException;
|
||||
import mjkf.xinke.common.listener.CommonDataChangeEventCenter;
|
||||
import mjkf.xinke.common.listener.CommonDataChangeListener;
|
||||
import mjkf.xinke.common.pojo.CommonResult;
|
||||
import mjkf.xinke.common.pojo.CommonWrapperInterface;
|
||||
import mjkf.xinke.common.util.CommonTimeFormatUtil;
|
||||
import mjkf.xinke.core.handler.GlobalExceptionUtil;
|
||||
import mjkf.xinke.sys.core.enums.SysBuildInEnum;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.sql.DataSource;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Snowy配置
|
||||
*
|
||||
*
|
||||
* @date 2021/10/9 14:24
|
||||
**/
|
||||
@Configuration
|
||||
@MapperScan(basePackages = {"mjkf.xinke.**.mapper, com.bstek.**.mapper"})
|
||||
public class GlobalConfigure implements WebMvcConfigurer {
|
||||
|
||||
private static final String COMMON_REPEAT_SUBMIT_CACHE_KEY = "common-repeatSubmit:";
|
||||
|
||||
@Resource
|
||||
private CommonCacheOperator commonCacheOperator;
|
||||
|
||||
/**
|
||||
* 无需登录的接口地址集合
|
||||
*/
|
||||
private static final String[] NO_LOGIN_PATH_ARR = {
|
||||
/* 主入口 */
|
||||
"/",
|
||||
|
||||
/* 静态资源 */
|
||||
"/favicon.ico",
|
||||
"/doc.html",
|
||||
"/webjars/**",
|
||||
"/swagger-resources/**",
|
||||
"/v2/api-docs",
|
||||
"/v2/api-docs-ext",
|
||||
"/configuration/ui",
|
||||
"/configuration/security",
|
||||
"/ureport/**",
|
||||
"/druid/**",
|
||||
"/images/**",
|
||||
|
||||
/* 认证相关 */
|
||||
"/auth/c/getPicCaptcha",
|
||||
"/auth/c/getPhoneValidCode",
|
||||
"/auth/c/doLogin",
|
||||
"/auth/c/doLoginByPhone",
|
||||
|
||||
"/auth/b/getPicCaptcha",
|
||||
"/auth/b/getPhoneValidCode",
|
||||
"/auth/b/doLogin",
|
||||
"/auth/b/doLoginByPhone",
|
||||
|
||||
/* 三方登录相关 */
|
||||
"/auth/third/render",
|
||||
"/auth/third/callback",
|
||||
|
||||
/* 系统基础配置 */
|
||||
"/dev/config/sysBaseList",
|
||||
|
||||
/* 系统字典树 */
|
||||
"/dev/dict/tree",
|
||||
|
||||
/* 文件下载 */
|
||||
"/dev/file/download",
|
||||
|
||||
/* 用户个人中心相关 */
|
||||
"/sys/userCenter/getPicCaptcha",
|
||||
"/sys/userCenter/findPasswordGetPhoneValidCode",
|
||||
"/sys/userCenter/findPasswordGetEmailValidCode",
|
||||
"/sys/userCenter/findPasswordByPhone",
|
||||
"/sys/userCenter/findPasswordByEmail",
|
||||
|
||||
/* 租户选择器*/
|
||||
"/ten/storage/tenSelector",
|
||||
|
||||
/* 支付相关回调通知 */
|
||||
"/pay/ali/notifyUrl",
|
||||
"/pay/wx/notifyUrl",
|
||||
"/pay/wx/authNotifyUrl",
|
||||
"/pay/wx/jsPay",
|
||||
"/pay/order/sample/doCreateOrder",
|
||||
};
|
||||
|
||||
/**
|
||||
* 仅超管使用的接口地址集合
|
||||
*/
|
||||
private static final String[] SUPER_PERMISSION_PATH_ARR = {
|
||||
"/auth/session/**",
|
||||
"/auth/third/page",
|
||||
"/client/user/**",
|
||||
"/sys/org/**",
|
||||
"/sys/position/**",
|
||||
"/sys/button/**",
|
||||
"/sys/menu/**",
|
||||
"/sys/module/**",
|
||||
"/sys/spa/**",
|
||||
"/sys/role/**",
|
||||
"/sys/user/**",
|
||||
"/dev/config/**",
|
||||
"/dev/dict/**",
|
||||
"/dev/email/page",
|
||||
"/dev/email/delete",
|
||||
"/dev/email/detail",
|
||||
"/dev/file/page",
|
||||
"/dev/file/list",
|
||||
"/dev/file/delete",
|
||||
"/dev/file/detail",
|
||||
"/dev/job/**",
|
||||
"/dev/log/**",
|
||||
"/dev/message/page",
|
||||
"/dev/message/delete",
|
||||
"/dev/message/detail",
|
||||
"/dev/monitor/**",
|
||||
"/dev/sms/page",
|
||||
"/dev/sms/delete",
|
||||
"/dev/sms/detail",
|
||||
"/gen/basic/**",
|
||||
"/gen/config/**",
|
||||
"/mobile/menu/**",
|
||||
"/mobile/module/**",
|
||||
"/flw/model/**",
|
||||
"/flw/templatePrint/**",
|
||||
"/flw/templateSn/**",
|
||||
"/pay/**",
|
||||
"/urp/**",
|
||||
"/dbs/**",
|
||||
"/ten/"
|
||||
};
|
||||
|
||||
/**
|
||||
* B端要排除的,相当于C端要认证的
|
||||
*/
|
||||
private static final String[] CLIENT_USER_PERMISSION_PATH_ARR = {
|
||||
"/auth/c/**",
|
||||
"/client/c/**"
|
||||
};
|
||||
|
||||
/**
|
||||
* 注册跨域过滤器
|
||||
*/
|
||||
@Bean
|
||||
public SaServletFilter getSaServletFilter() {
|
||||
return new SaServletFilter()
|
||||
// 指定拦截路由
|
||||
.addInclude("/**")
|
||||
|
||||
// 设置鉴权的接口
|
||||
.setAuth(r -> {
|
||||
// B端的接口校验B端登录
|
||||
SaRouter.match("/**")
|
||||
// 排除无需登录接口
|
||||
.notMatch(CollectionUtil.newArrayList(NO_LOGIN_PATH_ARR))
|
||||
// 排除C端认证接口
|
||||
.notMatch(CollectionUtil.newArrayList(CLIENT_USER_PERMISSION_PATH_ARR))
|
||||
// 校验B端登录
|
||||
.check(r1 -> StpUtil.checkLogin());
|
||||
|
||||
// C端的接口校验C端登录
|
||||
SaRouter.match("/**")
|
||||
// 排除无需登录接口
|
||||
.notMatch(CollectionUtil.newArrayList(NO_LOGIN_PATH_ARR))
|
||||
// 匹配C端认证接口
|
||||
.match(CollectionUtil.newArrayList(CLIENT_USER_PERMISSION_PATH_ARR))
|
||||
// 校验C端登录
|
||||
.check(r1 -> StpClientUtil.checkLogin());
|
||||
|
||||
// B端的超管接口校验B端超管角色
|
||||
SaRouter.match("/**")
|
||||
// 排除无需登录接口
|
||||
.notMatch(CollectionUtil.newArrayList(NO_LOGIN_PATH_ARR))
|
||||
// 匹配超管接口
|
||||
.match(CollectionUtil.newArrayList(SUPER_PERMISSION_PATH_ARR))
|
||||
// 校验B端超管角色
|
||||
.check(r1 -> StpUtil.checkRole(SysBuildInEnum.BUILD_IN_ROLE_CODE.getValue()));
|
||||
})
|
||||
|
||||
// 前置函数:在每次认证函数之前执行
|
||||
.setBeforeAuth(obj -> {
|
||||
|
||||
// ---------- 设置跨域响应头 ----------
|
||||
SaHolder.getResponse()
|
||||
|
||||
// 是否可以在iframe显示视图: DENY=不可以 | SAMEORIGIN=同域下可以 | ALLOW-FROM uri=指定域名下可以
|
||||
// .setHeader("X-Frame-Options", "SAMEORIGIN")
|
||||
|
||||
// 是否启用浏览器默认XSS防护: 0=禁用 | 1=启用 | 1; mode=block 启用, 并在检查到XSS攻击时,停止渲染页面
|
||||
.setHeader("X-XSS-Protection", "1; mode=block")
|
||||
// 禁用浏览器内容嗅探
|
||||
.setHeader("X-Content-Type-Options", "nosniff")
|
||||
// 允许指定域访问跨域资源
|
||||
.setHeader("Access-Control-Allow-Origin", "*")
|
||||
// 允许所有请求方式
|
||||
.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE")
|
||||
// 有效时间
|
||||
.setHeader("Access-Control-Max-Age", "3600")
|
||||
// 允许的header参数
|
||||
.setHeader("Access-Control-Allow-Headers", "*");
|
||||
|
||||
// 如果是预检请求,则立即返回到前端
|
||||
SaRouter.match(SaHttpMethod.OPTIONS)
|
||||
// OPTIONS预检请求,不做处理
|
||||
.free(r -> {})
|
||||
.back();
|
||||
})
|
||||
|
||||
// 异常处理
|
||||
.setError(e -> {
|
||||
// 由于过滤器中抛出的异常不进入全局异常处理,所以必须提供[异常处理函数]来处理[认证函数]里抛出的异常
|
||||
// 在[异常处理函数]里的返回值,将作为字符串输出到前端,此处统一转为JSON输出前端
|
||||
SaResponse saResponse = SaHolder.getResponse();
|
||||
saResponse.setHeader(Header.CONTENT_TYPE.getValue(), ContentType.JSON + ";charset=" + CharsetUtil.UTF_8);
|
||||
return GlobalExceptionUtil.getCommonResult((Exception) e);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* RedisTemplate序列化
|
||||
*
|
||||
*
|
||||
* @date 2022/6/21 17:01
|
||||
**/
|
||||
@Bean
|
||||
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
|
||||
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
|
||||
redisTemplate.setConnectionFactory(redisConnectionFactory);
|
||||
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
|
||||
redisTemplate.setKeySerializer(stringRedisSerializer);
|
||||
redisTemplate.setHashKeySerializer(stringRedisSerializer);
|
||||
Jackson2JsonRedisSerializer<?> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
|
||||
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
|
||||
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
|
||||
redisTemplate.afterPropertiesSet();
|
||||
return redisTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 静态资源映射
|
||||
*
|
||||
*
|
||||
* @date 2022/7/25 15:16
|
||||
**/
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
|
||||
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
|
||||
registry.addResourceHandler("/ureport/res/**").addResourceLocations("classpath:/META-INF/resources/ureport-asserts/");
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加节流防抖拦截器
|
||||
*
|
||||
*
|
||||
* @date 2022/6/20 15:18
|
||||
**/
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(new HandlerInterceptor() {
|
||||
@Override
|
||||
public boolean preHandle(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response,
|
||||
@NonNull Object handler) throws Exception {
|
||||
if (handler instanceof HandlerMethod) {
|
||||
HandlerMethod handlerMethod = (HandlerMethod) handler;
|
||||
Method method = handlerMethod.getMethod();
|
||||
CommonNoRepeat annotation = method.getAnnotation(CommonNoRepeat.class);
|
||||
if (ObjectUtil.isNotEmpty(annotation)) {
|
||||
JSONObject repeatSubmitJsonObject = this.isRepeatSubmit(request, annotation);
|
||||
if (repeatSubmitJsonObject.getBool("repeat")) {
|
||||
response.setCharacterEncoding(CharsetUtil.UTF_8);
|
||||
response.setContentType(ContentType.JSON.toString());
|
||||
response.getWriter().write(JSONUtil.toJsonStr(CommonResult.error("请求过于频繁,请" + repeatSubmitJsonObject.getStr("time") + "后再试")));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public JSONObject isRepeatSubmit(HttpServletRequest request, CommonNoRepeat annotation) {
|
||||
JSONObject jsonObject = JSONUtil.createObj();
|
||||
jsonObject.set("repeatParam", JSONUtil.toJsonStr(request.getParameterMap()));
|
||||
jsonObject.set("repeatTime", DateUtil.current());
|
||||
String url = request.getRequestURI();
|
||||
// 获取该接口缓存的限流数据
|
||||
Object cacheObj = commonCacheOperator.get(COMMON_REPEAT_SUBMIT_CACHE_KEY + url);
|
||||
if (ObjectUtil.isNotEmpty(cacheObj)) {
|
||||
JSONObject cacheJsonObject = JSONUtil.parseObj(cacheObj);
|
||||
if(cacheJsonObject.containsKey(url)) {
|
||||
JSONObject existRepeatJsonObject = cacheJsonObject.getJSONObject(url);
|
||||
// 如果与上次参数一致,且时间间隔小于要求的限流时长,则判定为重复提交
|
||||
if (jsonObject.getStr("repeatParam").equals(existRepeatJsonObject.getStr("repeatParam"))) {
|
||||
long interval = jsonObject.getLong("repeatTime") - existRepeatJsonObject.getLong("repeatTime");
|
||||
if(interval < annotation.interval()) {
|
||||
long secondsParam = (annotation.interval() - interval) / 1000;
|
||||
if(secondsParam == 0) {
|
||||
return JSONUtil.createObj().set("repeat", false);
|
||||
} else {
|
||||
return JSONUtil.createObj().set("repeat", true).set("time", CommonTimeFormatUtil.formatSeconds(secondsParam));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 缓存最新的该接口的限流数据,为防止缓存的数据过多,缓存时效为1小时
|
||||
commonCacheOperator.put(COMMON_REPEAT_SUBMIT_CACHE_KEY + url, JSONUtil.createObj().set(url, jsonObject), 60 * 60);
|
||||
return JSONUtil.createObj().set("repeat", false);
|
||||
}
|
||||
}).addPathPatterns("/**");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用Wrapper的AOP
|
||||
*
|
||||
*
|
||||
* @date 2022/9/15 21:24
|
||||
*/
|
||||
@Component
|
||||
@Aspect
|
||||
public static class CommonWrapperAop {
|
||||
|
||||
/**
|
||||
* 切入点
|
||||
*
|
||||
*
|
||||
* @date 2022/9/15 21:27
|
||||
*/
|
||||
@Pointcut("@annotation(mjkf.xinke.common.annotation.CommonWrapper)")
|
||||
private void wrapperPointcut() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行包装
|
||||
*
|
||||
*
|
||||
* @date 2022/9/15 21:27
|
||||
*/
|
||||
@Around("wrapperPointcut()")
|
||||
public Object doWrapper(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
|
||||
// 直接执行原有业务逻辑
|
||||
Object proceedResult = proceedingJoinPoint.proceed();
|
||||
return processWrapping(proceedingJoinPoint, proceedResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* 具体包装过程
|
||||
*
|
||||
*
|
||||
* @date 2022/9/15 21:27
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
private Object processWrapping(ProceedingJoinPoint proceedingJoinPoint, Object originResult) throws IllegalAccessException, InstantiationException {
|
||||
MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
|
||||
Method method = methodSignature.getMethod();
|
||||
CommonWrapper commonWrapper = method.getAnnotation(CommonWrapper.class);
|
||||
Class<? extends CommonWrapperInterface<?>>[] baseWrapperClasses = commonWrapper.value();
|
||||
if (ObjectUtil.isEmpty(baseWrapperClasses)) {
|
||||
return originResult;
|
||||
}
|
||||
if (!(originResult instanceof CommonResult)) {
|
||||
return originResult;
|
||||
}
|
||||
CommonResult commonResult = (CommonResult) originResult;
|
||||
Object beWrapped = commonResult.getData();
|
||||
if (ObjectUtil.isBasicType(beWrapped)) {
|
||||
throw new CommonException("被包装的值不能是基本类型");
|
||||
}
|
||||
if (beWrapped instanceof Page) {
|
||||
Page page = (Page) beWrapped;
|
||||
ArrayList<Map<String, Object>> maps = new ArrayList<>();
|
||||
for (Object wrappedItem : page.getRecords()) {
|
||||
maps.add(this.wrapPureObject(wrappedItem, baseWrapperClasses));
|
||||
}
|
||||
page.setRecords(maps);
|
||||
commonResult.setData(page);
|
||||
} else if (beWrapped instanceof Collection) {
|
||||
Collection collection = (Collection) beWrapped;
|
||||
List<Map<String, Object>> maps = new ArrayList<>();
|
||||
for (Object wrappedItem : collection) {
|
||||
maps.add(this.wrapPureObject(wrappedItem, baseWrapperClasses));
|
||||
}
|
||||
commonResult.setData(maps);
|
||||
} else if (ArrayUtil.isArray(beWrapped)) {
|
||||
Object[] objects = this.objToArray(beWrapped);
|
||||
ArrayList<Map<String, Object>> maps = new ArrayList<>();
|
||||
for (Object wrappedItem : objects) {
|
||||
maps.add(this.wrapPureObject(wrappedItem, baseWrapperClasses));
|
||||
}
|
||||
commonResult.setData(maps);
|
||||
} else {
|
||||
commonResult.setData(this.wrapPureObject(beWrapped, baseWrapperClasses));
|
||||
}
|
||||
return commonResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* 原始对象包装JSONObject
|
||||
*
|
||||
*
|
||||
* @date 2022/9/15 21:36
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
private JSONObject wrapPureObject(Object originModel, Class<? extends CommonWrapperInterface<?>>[] baseWrapperClasses) {
|
||||
JSONObject jsonObject = JSONUtil.parseObj(originModel);
|
||||
try {
|
||||
for (Class<? extends CommonWrapperInterface<?>> commonWrapperClass : baseWrapperClasses) {
|
||||
CommonWrapperInterface commonWrapperInterface = commonWrapperClass.newInstance();
|
||||
Map<String, Object> incrementFieldsMap = commonWrapperInterface.doWrap(originModel);
|
||||
jsonObject.putAll(incrementFieldsMap);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new CommonException("原始对象包装过程,字段转化异常:{}", e.getMessage());
|
||||
}
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Object转array
|
||||
*
|
||||
*
|
||||
* @date 2022/9/15 21:34
|
||||
*/
|
||||
private Object[] objToArray(Object object) {
|
||||
int length = Array.getLength(object);
|
||||
Object[] result = new Object[length];
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
result[i] = Array.get(object, i);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据库id选择器,用于Mapper.xml中
|
||||
* MyBatis可以根据不同的数据库厂商执行不同的语句
|
||||
*
|
||||
*
|
||||
* @date 2022/1/8 2:16
|
||||
*/
|
||||
@Component
|
||||
public static class CustomDbIdProvider implements DatabaseIdProvider {
|
||||
|
||||
@Override
|
||||
public String getDatabaseId(DataSource dataSource) throws SQLException {
|
||||
Connection conn = null;
|
||||
try {
|
||||
conn = dataSource.getConnection();
|
||||
String url = conn.getMetaData().getURL().toLowerCase();
|
||||
if (url.contains("jdbc:oracle")) {
|
||||
return "oracle";
|
||||
} else if (url.contains("jdbc:postgresql")) {
|
||||
return "pgsql";
|
||||
} else if (url.contains("jdbc:mysql")) {
|
||||
return "mysql";
|
||||
} else if (url.contains("jdbc:dm")) {
|
||||
return "dm";
|
||||
} else if (url.contains("jdbc:kingbase")) {
|
||||
return "kingbase";
|
||||
} else {
|
||||
return "mysql";
|
||||
}
|
||||
} finally {
|
||||
JdbcUtils.closeConnection(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义公共字段自动注入
|
||||
*
|
||||
*
|
||||
* @date 2020/3/31 15:42
|
||||
*/
|
||||
@Component
|
||||
public static class CustomMetaObjectHandler implements MetaObjectHandler {
|
||||
|
||||
/** 删除标志 */
|
||||
private static final String DELETE_FLAG = "deleteFlag";
|
||||
|
||||
/** 创建人 */
|
||||
private static final String CREATE_USER = "createUser";
|
||||
|
||||
/** 创建时间 */
|
||||
private static final String CREATE_TIME = "createTime";
|
||||
|
||||
/** 更新人 */
|
||||
private static final String UPDATE_USER = "updateUser";
|
||||
|
||||
/** 更新时间 */
|
||||
private static final String UPDATE_TIME = "updateTime";
|
||||
|
||||
@Override
|
||||
public void insertFill(MetaObject metaObject) {
|
||||
try {
|
||||
//为空则设置deleteFlag
|
||||
Object deleteFlag = metaObject.getValue(DELETE_FLAG);
|
||||
if (ObjectUtil.isNull(deleteFlag)) {
|
||||
setFieldValByName(DELETE_FLAG, EnumUtil.toString(CommonDeleteFlagEnum.NOT_DELETE), metaObject);
|
||||
}
|
||||
} catch (ReflectionException ignored) { }
|
||||
try {
|
||||
//为空则设置createUser
|
||||
Object createUser = metaObject.getValue(CREATE_USER);
|
||||
if (ObjectUtil.isNull(createUser)) {
|
||||
setFieldValByName(CREATE_USER, this.getUserId(), metaObject);
|
||||
}
|
||||
} catch (ReflectionException ignored) { }
|
||||
try {
|
||||
//为空则设置createTime
|
||||
Object createTime = metaObject.getValue(CREATE_TIME);
|
||||
if (ObjectUtil.isNull(createTime)) {
|
||||
setFieldValByName(CREATE_TIME, DateTime.now(), metaObject);
|
||||
}
|
||||
} catch (ReflectionException ignored) { }
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFill(MetaObject metaObject) {
|
||||
try {
|
||||
//设置updateUser
|
||||
setFieldValByName(UPDATE_USER, this.getUserId(), metaObject);
|
||||
} catch (ReflectionException ignored) { }
|
||||
try {
|
||||
//设置updateTime
|
||||
setFieldValByName(UPDATE_TIME, DateTime.now(), metaObject);
|
||||
} catch (ReflectionException ignored) { }
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户id
|
||||
*/
|
||||
private String getUserId() {
|
||||
try {
|
||||
String loginId = StpUtil.getLoginIdAsString();
|
||||
if (ObjectUtil.isNotEmpty(loginId)) {
|
||||
return loginId;
|
||||
} else {
|
||||
return "-1";
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return "-1";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册数据变化事件中心 事件发布器
|
||||
*
|
||||
*
|
||||
* @date 2023/3/3 14:27
|
||||
**/
|
||||
@Resource
|
||||
public void registerListenerList(List<CommonDataChangeListener> dataChangeListenerList) {
|
||||
CommonDataChangeEventCenter.registerListenerList(dataChangeListenerList);
|
||||
}
|
||||
}
|
@@ -0,0 +1,64 @@
|
||||
|
||||
package mjkf.xinke.core.handler;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.http.HttpStatus;
|
||||
import org.springframework.boot.web.error.ErrorAttributeOptions;
|
||||
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
import mjkf.xinke.common.exception.CommonException;
|
||||
import mjkf.xinke.common.pojo.CommonResult;
|
||||
import mjkf.xinke.common.util.CommonServletUtil;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 将未知错误异常,输出格式重写为我们熟悉的响应格式
|
||||
*
|
||||
*
|
||||
* @date 2021/10/9 15:24
|
||||
**/
|
||||
@Component
|
||||
public class GlobalErrorAttributesHandler extends DefaultErrorAttributes {
|
||||
@Override
|
||||
public Map<String, Object> getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions attributeOptions) {
|
||||
// 获取spring默认的返回内容
|
||||
Map<String, Object> defaultErrorAttributes = super.getErrorAttributes(webRequest, attributeOptions);
|
||||
|
||||
// 获取其状态码
|
||||
Object status = defaultErrorAttributes.get("status");
|
||||
if (ObjectUtil.isNotEmpty(status)) {
|
||||
// 如果其为404,则处理
|
||||
if (HttpStatus.HTTP_NOT_FOUND == Convert.toInt(status)) {
|
||||
Object path = defaultErrorAttributes.get("path");
|
||||
if(ObjectUtil.isNotEmpty(path)) {
|
||||
return BeanUtil.beanToMap(CommonResult.get(HttpStatus.HTTP_NOT_FOUND, "路径不存在,请求地址:" +
|
||||
Convert.toStr(path), null));
|
||||
} else {
|
||||
return BeanUtil.beanToMap(CommonResult.get(HttpStatus.HTTP_NOT_FOUND, "路径不存在", null));
|
||||
}
|
||||
} else {
|
||||
return BeanUtil.beanToMap(CommonResult.get(HttpStatus.HTTP_INTERNAL_ERROR, "服务器异常,请求地址:" +
|
||||
CommonServletUtil.getRequest().getRequestURL(), null));
|
||||
}
|
||||
}
|
||||
|
||||
// 如果返回的异常是CommonException,则按CommonException响应的内容进行返回
|
||||
Throwable throwable = this.getError(webRequest);
|
||||
if (ObjectUtil.isNotEmpty(throwable)) {
|
||||
if (throwable instanceof CommonException) {
|
||||
CommonException commonException = (CommonException) throwable;
|
||||
return BeanUtil.beanToMap(CommonResult.error(commonException.getMsg()));
|
||||
} else {
|
||||
return BeanUtil.beanToMap(CommonResult.get(HttpStatus.HTTP_INTERNAL_ERROR, "服务器异常,请求地址:" +
|
||||
CommonServletUtil.getRequest().getRequestURL(), null));
|
||||
}
|
||||
} else {
|
||||
// throwable为空,则直接返回默认异常
|
||||
return BeanUtil.beanToMap(CommonResult.error());
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,58 @@
|
||||
|
||||
package mjkf.xinke.core.handler;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import mjkf.xinke.common.exception.CommonException;
|
||||
import mjkf.xinke.common.pojo.CommonResult;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* 全局异常页面处理器,覆盖默认的Whitelabel Error Page
|
||||
*
|
||||
*
|
||||
* @date 2022/2/11 15:41
|
||||
**/
|
||||
@Slf4j
|
||||
@RestController
|
||||
public class GlobalErrorViewController {
|
||||
|
||||
/**
|
||||
* Error页面视图,直接响应JSON
|
||||
*
|
||||
*
|
||||
* @date 2022/2/11 16:11
|
||||
**/
|
||||
@RequestMapping("/errorView")
|
||||
public CommonResult<String> globalError(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||
CommonResult<String> commonResult = new CommonResult<>(404, "路径不存在", null);
|
||||
Object model = request.getAttribute("model");
|
||||
if(ObjectUtil.isNotEmpty(model)) {
|
||||
if(model instanceof Exception){
|
||||
if(model instanceof CommonException) {
|
||||
JSONObject errorObj = JSONUtil.parseObj(model);
|
||||
Integer code = errorObj.getInt("code");
|
||||
String msg = errorObj.getStr("msg");
|
||||
if(ObjectUtil.isAllNotEmpty(code, msg)) {
|
||||
commonResult.setCode(code).setMsg(msg);
|
||||
} else if(ObjectUtil.isNotEmpty(msg)) {
|
||||
commonResult = CommonResult.error(msg);
|
||||
} else {
|
||||
commonResult = CommonResult.error();
|
||||
}
|
||||
} else {
|
||||
commonResult = CommonResult.error();
|
||||
log.error(">>> 服务器未知异常,具体信息:", (Exception) model);
|
||||
}
|
||||
}
|
||||
}
|
||||
return commonResult;
|
||||
}
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
|
||||
package mjkf.xinke.core.handler;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 全局异常页面处理器,覆盖默认的Whitelabel Error Page
|
||||
*
|
||||
*
|
||||
* @date 2022/2/11 15:41
|
||||
**/
|
||||
@RestController
|
||||
public class GlobalErrorViewHandler extends BasicErrorController {
|
||||
|
||||
public GlobalErrorViewHandler(ServerProperties serverProperties) {
|
||||
super(new GlobalErrorAttributesHandler(), serverProperties.getError());
|
||||
}
|
||||
|
||||
/**
|
||||
* 覆盖默认的Json响应
|
||||
*
|
||||
*
|
||||
* @date 2022/2/11 15:47
|
||||
**/
|
||||
@Override
|
||||
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
|
||||
Map<String, Object> defaultErrorAttributes = super.getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.ALL));
|
||||
Integer code = Convert.toInt(defaultErrorAttributes.get("code"));
|
||||
return new ResponseEntity<>(defaultErrorAttributes, HttpStatus.valueOf(ObjectUtil.isNotEmpty(code)?code:500));
|
||||
}
|
||||
|
||||
/**
|
||||
* 覆盖默认的错误页面,响应JSON
|
||||
*
|
||||
*
|
||||
* @date 2022/2/12 21:55
|
||||
*/
|
||||
@Override
|
||||
@RequestMapping(produces = {"text/html"})
|
||||
public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
|
||||
HttpStatus status = this.getStatus(request);
|
||||
Map<String, Object> model = Collections.unmodifiableMap(this.getErrorAttributes(request, this.getErrorAttributeOptions(request, MediaType.TEXT_HTML)));
|
||||
response.setStatus(status.value());
|
||||
ModelAndView modelAndView = this.resolveErrorView(request, response, status, model);
|
||||
request.setAttribute("model", model);
|
||||
return modelAndView != null ? modelAndView : new ModelAndView("errorView", model);
|
||||
}
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
|
||||
package mjkf.xinke.core.handler;
|
||||
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import mjkf.xinke.common.pojo.CommonResult;
|
||||
|
||||
/**
|
||||
* 全局异常处理器
|
||||
*
|
||||
*
|
||||
* @date 2021/10/9 14:59
|
||||
**/
|
||||
@ControllerAdvice
|
||||
public class GlobalExceptionHandler {
|
||||
|
||||
/**
|
||||
* 不同异常返回不同结果
|
||||
*
|
||||
*
|
||||
* @date 2022/7/28 16:54
|
||||
**/
|
||||
@ResponseBody
|
||||
@ExceptionHandler
|
||||
public CommonResult<String> handleException(Exception e) {
|
||||
return GlobalExceptionUtil.getCommonResult(e);
|
||||
}
|
||||
}
|
179
src/main/java/mjkf/xinke/core/handler/GlobalExceptionUtil.java
Normal file
179
src/main/java/mjkf/xinke/core/handler/GlobalExceptionUtil.java
Normal file
@@ -0,0 +1,179 @@
|
||||
|
||||
package mjkf.xinke.core.handler;
|
||||
|
||||
import cn.dev33.satoken.exception.SaTokenException;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpStatus;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.ibatis.exceptions.PersistenceException;
|
||||
import org.mybatis.spring.MyBatisSystemException;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.validation.BindingResult;
|
||||
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.multipart.MultipartException;
|
||||
import org.springframework.web.multipart.support.MissingServletRequestPartException;
|
||||
import mjkf.xinke.auth.core.util.AuthExceptionUtil;
|
||||
import mjkf.xinke.common.exception.CommonException;
|
||||
import mjkf.xinke.common.pojo.CommonResult;
|
||||
import mjkf.xinke.common.util.CommonServletUtil;
|
||||
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.ConstraintViolationException;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 全局异常处理工具类,将异常转为通用结果
|
||||
*
|
||||
*
|
||||
* @date 2021/12/18 16:44
|
||||
*/
|
||||
@Slf4j
|
||||
public class GlobalExceptionUtil {
|
||||
|
||||
/**
|
||||
* 根据错误类型获取对应的CommonResult
|
||||
*
|
||||
*
|
||||
* @date 2021/10/11 15:52
|
||||
**/
|
||||
public static CommonResult<String> getCommonResult(Exception e) {
|
||||
CommonResult<String> commonResult;
|
||||
if (e instanceof HttpRequestMethodNotSupportedException) {
|
||||
|
||||
// 如果是请求方法异常 405
|
||||
String method = CommonServletUtil.getRequest().getMethod();
|
||||
if (HttpMethod.GET.toString().equals(method)) {
|
||||
commonResult = CommonResult.get(HttpStatus.HTTP_BAD_METHOD, "请求方法应为POST", null);
|
||||
} else if(HttpMethod.POST.toString().equals(method)) {
|
||||
commonResult = CommonResult.get(HttpStatus.HTTP_BAD_METHOD, "请求方法应为GET", null);
|
||||
} else {
|
||||
commonResult = CommonResult.get(HttpStatus.HTTP_BAD_METHOD, "请求方法仅支持GET或POST", null);
|
||||
}
|
||||
} else if (e instanceof HttpMessageNotReadableException) {
|
||||
log.error(">>> 参数传递格式异常:", e);
|
||||
// 如果是参数传递格式不支持异常 415
|
||||
if (e.getMessage().contains("JSON parse error")) {
|
||||
//JSON格式转换错误特殊提示
|
||||
commonResult = CommonResult.get(HttpStatus.HTTP_UNSUPPORTED_TYPE, "参数格式错误", null);
|
||||
} else {
|
||||
commonResult = CommonResult.get(HttpStatus.HTTP_UNSUPPORTED_TYPE, "请使用JSON方式传参", null);
|
||||
}
|
||||
} else if (e instanceof HttpMediaTypeNotSupportedException) {
|
||||
log.error(">>> 参数传递格式异常:", e);
|
||||
// 如果是JSON参数格式错误异常 415
|
||||
commonResult = CommonResult.get(HttpStatus.HTTP_UNSUPPORTED_TYPE, "参数格式错误", null);
|
||||
} else if (e instanceof MethodArgumentNotValidException) {
|
||||
|
||||
// 如果是参数校验异常(MethodArgumentNotValidException) 415
|
||||
MethodArgumentNotValidException methodArgumentNotValidException = (MethodArgumentNotValidException) e;
|
||||
commonResult = CommonResult.get(HttpStatus.HTTP_UNSUPPORTED_TYPE, getArgNotValidMessage(methodArgumentNotValidException.getBindingResult()), null);
|
||||
} else if (e instanceof BindException) {
|
||||
|
||||
// 如果是参数校验异常(BindException) 415
|
||||
BindException bindException = (BindException) e;
|
||||
commonResult = CommonResult.get(HttpStatus.HTTP_UNSUPPORTED_TYPE, getArgNotValidMessage(bindException.getBindingResult()), null);
|
||||
} else if (e instanceof ConstraintViolationException) {
|
||||
|
||||
// 如果是参数校验异常(ConstraintViolationException) 415
|
||||
ConstraintViolationException constraintViolationException = (ConstraintViolationException) e;
|
||||
commonResult = CommonResult.get(HttpStatus.HTTP_UNSUPPORTED_TYPE, getArgNotValidMessage(constraintViolationException.getConstraintViolations()), null);
|
||||
} else if (e instanceof MissingServletRequestParameterException) {
|
||||
|
||||
// 如果是参数校验异常(MissingServletRequestParameterException) 415
|
||||
MissingServletRequestParameterException missingServletRequestParameterException = (MissingServletRequestParameterException) e;
|
||||
commonResult = CommonResult.get(HttpStatus.HTTP_UNSUPPORTED_TYPE, missingServletRequestParameterException.getMessage(), null);
|
||||
}
|
||||
else if (e instanceof MultipartException) {
|
||||
log.error(">>> 文件上传参数异常:", e);
|
||||
//文件上传错误特殊提示
|
||||
commonResult = CommonResult.error("请使用multipart/form-data方式上传文件");
|
||||
} else if (e instanceof MissingServletRequestPartException) {
|
||||
log.error(">>> 文件上传参数异常:", e);
|
||||
//文件上传错误特殊提示
|
||||
commonResult = CommonResult.error("请选择要上传的文件并检查文件参数名称是否正确");
|
||||
} else if (e instanceof SaTokenException) {
|
||||
|
||||
// 如果是SaToken相关异常,则由AuthExceptionUtil处理
|
||||
return AuthExceptionUtil.getCommonResult(e);
|
||||
} else if(e instanceof MyBatisSystemException) {
|
||||
|
||||
// 如果是MyBatisSystemException
|
||||
Throwable cause = e.getCause();
|
||||
if (cause instanceof PersistenceException) {
|
||||
Throwable secondCause = cause.getCause();
|
||||
if (secondCause instanceof CommonException) {
|
||||
CommonException commonException = (CommonException) secondCause;
|
||||
commonResult = CommonResult.get(commonException.getCode(), commonException.getMsg(), null);
|
||||
} else {
|
||||
log.error(">>> 数据操作异常:", e);
|
||||
commonResult = CommonResult.error("数据操作异常");
|
||||
}
|
||||
}else {
|
||||
log.error(">>> 数据操作异常:", e);
|
||||
commonResult = CommonResult.error("数据操作异常");
|
||||
}
|
||||
} else if (e instanceof CommonException) {
|
||||
|
||||
// 通用业务异常,直接返回给前端
|
||||
CommonException commonException = (CommonException) e;
|
||||
commonResult = CommonResult.get(commonException.getCode(), commonException.getMsg(), null);
|
||||
} else {
|
||||
// 未知异常打印详情
|
||||
log.error(">>> 服务器未知异常,请求地址:{},具体信息:", CommonServletUtil.getRequest().getRequestURL(), e);
|
||||
// 未知异常返回服务器异常
|
||||
commonResult = CommonResult.error();
|
||||
}
|
||||
return commonResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求参数不正确的提示信息,多个信息,拼接成用逗号分隔的形式
|
||||
*
|
||||
*
|
||||
* @date 2021/10/12 11:14
|
||||
**/
|
||||
public static String getArgNotValidMessage(Set<ConstraintViolation<?>> constraintViolationSet) {
|
||||
if (ObjectUtil.isEmpty(constraintViolationSet)) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder stringBuilder = StrUtil.builder();
|
||||
|
||||
// 多个错误用逗号分隔
|
||||
for (ConstraintViolation<?> constraintViolation : constraintViolationSet) {
|
||||
stringBuilder.append(StrUtil.COMMA).append(constraintViolation.getMessage());
|
||||
}
|
||||
|
||||
// 最终把首部的逗号去掉
|
||||
return StrUtil.removePrefix(stringBuilder.toString(), StrUtil.COMMA);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求参数不正确的提示信息,多个信息,拼接成用逗号分隔的形式
|
||||
*
|
||||
*
|
||||
* @date 2021/10/12 11:14
|
||||
**/
|
||||
public static String getArgNotValidMessage(BindingResult bindingResult) {
|
||||
if (ObjectUtil.isNull(bindingResult)) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder stringBuilder = StrUtil.builder();
|
||||
|
||||
// 多个错误用逗号分隔
|
||||
List<ObjectError> allErrorInfos = bindingResult.getAllErrors();
|
||||
for (ObjectError error : allErrorInfos) {
|
||||
stringBuilder.append(StrUtil.COMMA).append(error.getDefaultMessage());
|
||||
}
|
||||
|
||||
// 最终把首部的逗号去掉
|
||||
return StrUtil.removePrefix(stringBuilder.toString(), StrUtil.COMMA);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user