This commit is contained in:
六如
2024-11-04 00:01:02 +08:00
parent 0e29510d0e
commit f76eab3c30
20 changed files with 617 additions and 420 deletions

View File

@@ -0,0 +1,40 @@
package com.gitee.sop.support.exception;
import com.gitee.sop.support.message.OpenError;
import com.gitee.sop.support.message.OpenMessage;
import com.gitee.sop.support.message.OpenMessageFactory;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Locale;
/**
* @author 六如
*/
@Getter
@AllArgsConstructor
public class OpenException extends RuntimeException {
private static final long serialVersionUID = -8059687941272829442L;
private String subCode;
private String subMsg;
private String solution;
public OpenException(OpenError openError, Locale locale, Object... params) {
this.subCode = openError.getSubCode();
OpenMessage openMessage = OpenMessageFactory.getError(openError, locale, params);
this.subMsg = openMessage.getSubMsg();
this.solution = openMessage.getSolution();
}
public OpenException(OpenError openError, Object... params) {
this(openError, Locale.SIMPLIFIED_CHINESE, params);
}
@Override
public String toString() {
return String.join("@@", subCode, subMsg, solution);
}
}

View File

@@ -0,0 +1,16 @@
package com.gitee.sop.support.message;
/**
* 定义错误返回
* @author 六如
*/
public interface OpenError {
/**
* sub_code明细返回码
* @return sub_code明细返回码
*/
String getSubCode();
String modulePrefix();
}

View File

@@ -0,0 +1,26 @@
package com.gitee.sop.support.message;
/**
* 定义错误返回
*
* @author 六如
*/
public interface OpenMessage {
/**
* @return 明细返回码
*/
String getSubCode();
/**
* @return 明细信息
*/
String getSubMsg();
/**
* @return 解决方案
*/
String getSolution();
}

View File

@@ -0,0 +1,116 @@
package com.gitee.sop.support.message;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;
/**
* 负责构建错误消息
*
* @author 六如
*/
public class OpenMessageFactory {
static Logger logger = Logger.getLogger(OpenMessageFactory.class.getName());
private static final String SOLUTION = ".solution";
private OpenMessageFactory() {
}
public static final String SYS_ERR = "系统错误";
private static final String I18N_OPEN_ERROR = "i18n/isp/error";
private static final Set<String> noModuleCache = new HashSet<>();
private static final Map<String, OpenMessage> errorCache = new ConcurrentHashMap<>(64);
/**
* 错误信息的国际化信息
*/
private static MessageSourceAccessor errorMessageSourceAccessor;
/**
* 设置国际化资源信息
*/
public static void initMessageSource(List<String> isvModules) {
HashSet<String> baseNamesSet = new HashSet<>();
baseNamesSet.add(I18N_OPEN_ERROR);
if (!isvModules.isEmpty()) {
baseNamesSet.addAll(isvModules);
}
String[] totalBaseNames = baseNamesSet.toArray(new String[0]);
logger.info("加载错误码国际化资源:" + StringUtils.arrayToCommaDelimitedString(totalBaseNames));
ResourceBundleMessageSource bundleMessageSource = new ResourceBundleMessageSource();
bundleMessageSource.setBasenames(totalBaseNames);
MessageSourceAccessor messageSourceAccessor = new MessageSourceAccessor(bundleMessageSource);
setErrorMessageSourceAccessor(messageSourceAccessor);
}
/**
* 通过ErrorMetaLocaleparams构建国际化错误消息
*
* @param openError 错误信息
* @param locale 本地化
* @param params 参数
* @return 如果没有配置国际化消息则直接返回errorMeta中的信息
*/
public static OpenMessage getError(OpenError openError, Locale locale, Object... params) {
Assert.notNull(locale, "未设置Locale");
String modulePrefix = openError.modulePrefix();
String subCode = openError.getSubCode();
// isp.error_isp.unknow-error=Service is temporarily unavailable
String subMsg = getErrorMessage(modulePrefix + subCode, locale, params);
if (ObjectUtils.isEmpty(subMsg)) {
subMsg = SYS_ERR;
}
// isp.error_isp.unknow-error.solution=Service is temporarily unavailable
String solution = getErrorMessage(modulePrefix + subCode + SOLUTION, locale, params);
if (ObjectUtils.isEmpty(solution)) {
solution = "";
}
return new ServiceMessageImpl(subCode, subMsg, solution);
}
public static void setErrorMessageSourceAccessor(MessageSourceAccessor errorMessageSourceAccessor) {
OpenMessageFactory.errorMessageSourceAccessor = errorMessageSourceAccessor;
}
/**
* 返回本地化信息
*
* @param module 错误模块
* @param locale 本地化
* @param params 参数
* @return 返回信息
*/
public static String getErrorMessage(String module, Locale locale, Object... params) {
if (noModuleCache.contains(module)) {
return null;
}
try {
return errorMessageSourceAccessor.getMessage(module, params, locale);
} catch (Exception e) {
noModuleCache.add(module);
return null;
}
}
}

View File

@@ -0,0 +1,15 @@
package com.gitee.sop.support.message;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
* @author 六如
*/
@Data
@AllArgsConstructor
public class ServiceMessageImpl implements OpenMessage {
private String subCode;
private String subMsg;
private String solution;
}

View File

@@ -2,6 +2,7 @@ package com.gitee.sop.support.register;
import com.alibaba.fastjson2.JSON;
import com.gitee.sop.support.annotation.Open;
import com.gitee.sop.support.message.OpenMessageFactory;
import com.gitee.sop.support.service.ApiRegisterService;
import com.gitee.sop.support.service.dto.RegisterDTO;
import com.gitee.sop.support.service.dto.RegisterResult;
@@ -11,11 +12,14 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.dubbo.config.annotation.DubboService;
import java.io.File;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
@@ -32,6 +36,7 @@ import java.util.stream.Stream;
public class ApiRegister {
private static final Log LOG = LogFactory.getLog(ApiRegister.class);
public static final String I18N_ROOT = "i18n";
private final ApiRegisterService apiRegisterService;
@@ -49,6 +54,47 @@ public class ApiRegister {
doWithMethod(objClass, (interfaceClass, method, open) ->
this.regApi(appName, interfaceClass, method, open));
}
initMessage();
}
protected void initMessage() {
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
URL i18n = contextClassLoader.getResource(I18N_ROOT);
if (i18n == null) {
return;
}
String file = i18n.getFile();
File i18nFolder = new File(file);
Set<String> isvModuleList = new HashSet<>();
File[] folders = i18nFolder.listFiles();
if (folders == null) {
return;
}
for (File listFile : folders) {
if (listFile.isDirectory()) {
File[] files = listFile.listFiles();
if (files == null) {
continue;
}
for (File subFile : files) {
// i18n/isp/bizerror_en.properties
String name = subFile.getName();
int i = name.indexOf("_");
String moduleName = name.substring(0, i);
String fullModuleName = String.join("/", I18N_ROOT, listFile.getName(), moduleName);
isvModuleList.add(fullModuleName);
}
} else {
// i18n/isp/bizerror_en.properties
String name = listFile.getName();
int i = name.indexOf("_");
String moduleName = name.substring(0, i);
String fullModuleName = String.join("/", I18N_ROOT, moduleName);
isvModuleList.add(fullModuleName);
}
}
OpenMessageFactory.initMessageSource(new ArrayList<>(isvModuleList));
}
protected void doWithMethod(Class<?> objClass, RegisterCallback callback) {