This commit is contained in:
六如
2024-11-07 22:55:06 +08:00
parent 5956af3564
commit 9e05259d92
45 changed files with 534 additions and 1426 deletions

View File

@@ -1,10 +1,11 @@
package com.gitee.sop.gateway.config;
import com.gitee.sop.gateway.message.ErrorFactory;
import com.gitee.sop.gateway.service.ParamExecutor;
import com.gitee.sop.gateway.service.ParamExecutorImpl;
import com.gitee.sop.gateway.service.RouteService;
import com.gitee.sop.gateway.service.RouteServiceImpl;
import com.gitee.sop.gateway.service.Serde;
import com.gitee.sop.gateway.service.SerdeImpl;
import com.gitee.sop.gateway.service.interceptor.internal.ResultRouteInterceptor;
import com.gitee.sop.gateway.service.manager.ApiManager;
import com.gitee.sop.gateway.service.manager.IsvApiPermissionManager;
@@ -18,6 +19,7 @@ import com.gitee.sop.gateway.service.manager.impl.RedisApiManagerImpl;
import com.gitee.sop.gateway.service.manager.impl.RedisIsvApiPermissionManagerImpl;
import com.gitee.sop.gateway.service.manager.impl.RedisIsvManagerImpl;
import com.gitee.sop.gateway.service.manager.impl.RedisSecretManager;
import com.gitee.sop.support.message.OpenMessageFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -25,13 +27,14 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
import java.util.Collections;
/**
* @author 六如
*/
@Configuration
@Slf4j
public class IndexConfig {
public class GatewayConfig {
@Bean
@ConditionalOnProperty(value = "gateway.manager.api", havingValue = "local", matchIfMissing = true)
@@ -101,8 +104,14 @@ public class IndexConfig {
return new RouteServiceImpl();
}
@Bean
@ConditionalOnMissingBean
public Serde serde() {
return new SerdeImpl();
}
@PostConstruct
public void init() {
ErrorFactory.initMessageSource(null);
OpenMessageFactory.initMessage();
}
}

View File

@@ -31,7 +31,7 @@ public class ApiException extends RuntimeException {
}
public IError getError() {
return errorEnum.getErrorMeta().getError(locale, params);
return errorEnum.getError(locale, params);
}
public ErrorEnum getErrorEnum() {
@@ -41,7 +41,7 @@ public class ApiException extends RuntimeException {
@Override
public String getMessage() {
String message = super.getMessage();
return message == null ? errorEnum.getErrorMeta().toString() : message;
return message == null ? errorEnum.getSubCode() : message;
}
}

View File

@@ -43,20 +43,26 @@ public class ExceptionExecutorImpl implements ExceptionExecutor {
String errorMsg;
if (matcher.find()) {
errorMsg = matcher.group(1);
// isv.common-error@@系统错误@@
String[] msgAr = errorMsg.split("@@");
String subCode = msgAr[0];
String subMsg = msgAr[1];
String solution = msgAr.length == 3 ? msgAr[2] : null;
return ApiResponse.error(
ErrorEnum.BIZ_ERROR,
apiRequestContext.getLocale(),
subCode,
subMsg,
solution
);
} else {
errorMsg = "biz-error@@系统错误";
ErrorEnum bizError = ErrorEnum.ISP_SERVICE_UNKNOWN_ERROR;
return ApiResponse.error(bizError.getError(apiRequestContext.getLocale()));
}
// isv.common-error@@系统错误@@
String[] msgAr = errorMsg.split("@@");
return ApiResponse.error(
ErrorEnum.BIZ_ERROR,
apiRequestContext.getLocale(),
msgAr[0],
msgAr[1]
);
}
} else if (e instanceof ApiException) {
return ApiResponse.error(((ApiException) e));
return ApiResponse.error(((ApiException) e).getError());
}
return ApiResponse.error(ErrorEnum.ISP_SERVICE_UNKNOWN_ERROR, apiRequestContext.getLocale());
}

View File

@@ -0,0 +1,44 @@
package com.gitee.sop.gateway.message;
import com.gitee.sop.support.message.I18nMessage;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author 六如
*/
@Getter
@AllArgsConstructor
public enum CodeEnum implements I18nMessage {
SUCCESS("0"),
/**
* 认证异常
*/
AUTH("20001"),
/**
* 缺少参数
*/
MISSING("40001"),
/**
* 错误参数
*/
INVALID("40002"),
/**
* 业务异常
*/
BIZ("50003"),
/**
* 权限异常
*/
ISV_PERM("40006"),
/**
* 未知异常
*/
UNKNOWN("99999");
private final String configKey;
public String getCode() {
return configKey;
}
}

View File

@@ -1,228 +1,246 @@
package com.gitee.sop.gateway.message;
import com.gitee.sop.support.message.I18nMessage;
import com.gitee.sop.support.message.OpenMessage;
import com.gitee.sop.support.message.OpenMessageFactory;
import lombok.Getter;
import java.util.Locale;
/**
* 网关错误定义
*
* @author 六如
*/
public enum ErrorEnum {
@Getter
public enum ErrorEnum implements I18nMessage {
/**
* 成功
*/
SUCCESS(Codes.CODE_SUCCESS, ""),
SUCCESS(CodeEnum.SUCCESS, ""),
/**
* 服务暂不可用
*/
ISP_UNKNOWN_ERROR(Codes.CODE_UNKNOWN, "isp.unknown-error"),
ISP_UNKNOWN_ERROR(CodeEnum.UNKNOWN, "isp.unknown-error"),
/**
* 微服务未知错误
*/
ISP_SERVICE_UNKNOWN_ERROR(Codes.CODE_UNKNOWN, "isp.service-unknown-error"),
ISP_SERVICE_UNKNOWN_ERROR(CodeEnum.UNKNOWN, "isp.service-unknown-error"),
/**
* 服务不可用,路由被禁用
*/
ISP_API_DISABLED(Codes.CODE_UNKNOWN, "isp.service-not-available"),
ISP_API_DISABLED(CodeEnum.UNKNOWN, "isp.service-not-available"),
/**
* 网关响应超时
*/
ISP_GATEWAY_RESPONSE_TIMEOUT(Codes.CODE_UNKNOWN, "isp.gateway-response-timeout"),
ISP_GATEWAY_RESPONSE_TIMEOUT(CodeEnum.UNKNOWN, "isp.gateway-response-timeout"),
/**
* 限流处理
*/
ISV_REQUEST_LIMIT(Codes.CODE_UNKNOWN, "isv.service-busy"),
ISV_REQUEST_LIMIT(CodeEnum.UNKNOWN, "isv.service-busy"),
/**
* 无效的访问令牌
*/
AOP_INVALID_AUTH_TOKEN(Codes.CODE_AUTH, "aop.invalid-auth-token"),
AOP_INVALID_AUTH_TOKEN(CodeEnum.AUTH, "aop.invalid-auth-token"),
/**
* 访问令牌已过期
*/
AOP_AUTH_TOKEN_TIME_OUT(Codes.CODE_AUTH, "aop.auth-token-time-out"),
AOP_AUTH_TOKEN_TIME_OUT(CodeEnum.AUTH, "aop.auth-token-time-out"),
/**
* 无效的应用授权令牌
*/
AOP_INVALID_APP_AUTH_TOKEN(Codes.CODE_AUTH, "aop.invalid-app-auth-token"),
AOP_INVALID_APP_AUTH_TOKEN(CodeEnum.AUTH, "aop.invalid-app-auth-token"),
/**
* 商户未授权当前接口
*/
AOP_INVALID_APP_AUTH_TOKEN_NO_API(Codes.CODE_AUTH, "aop.invalid-app-auth-token-no-api"),
AOP_INVALID_APP_AUTH_TOKEN_NO_API(CodeEnum.AUTH, "aop.invalid-app-auth-token-no-api"),
/**
* 应用授权令牌已过期
*/
AOP_APP_AUTH_TOKEN_TIME_OUT(Codes.CODE_AUTH, "aop.app-auth-token-time-out"),
AOP_APP_AUTH_TOKEN_TIME_OUT(CodeEnum.AUTH, "aop.app-auth-token-time-out"),
/**
* 商户未签约任何产品
*/
AOP_NO_PRODUCT_REG_BY_PARTNER(Codes.CODE_AUTH, "aop.no-product-reg-by-partner"),
AOP_NO_PRODUCT_REG_BY_PARTNER(CodeEnum.AUTH, "aop.no-product-reg-by-partner"),
/**
* 缺少方法名参数
*/
ISV_MISSING_METHOD(Codes.CODE_MISSING, "isv.missing-method"),
ISV_MISSING_METHOD(CodeEnum.MISSING, "isv.missing-method"),
/**
* 缺少签名参数
*/
ISV_MISSING_SIGNATURE(Codes.CODE_MISSING, "isv.missing-signature"),
ISV_MISSING_SIGNATURE(CodeEnum.MISSING, "isv.missing-signature"),
/**
* 缺少签名类型参数
*/
ISV_MISSING_SIGNATURE_TYPE(Codes.CODE_MISSING, "isv.missing-signature-type"),
ISV_MISSING_SIGNATURE_TYPE(CodeEnum.MISSING, "isv.missing-signature-type"),
/**
* 缺少签名配置
*/
ISV_MISSING_SIGNATURE_KEY(Codes.CODE_MISSING, "isv.missing-signature-key"),
ISV_MISSING_SIGNATURE_KEY(CodeEnum.MISSING, "isv.missing-signature-key"),
/**
* 缺少appId参数
*/
ISV_MISSING_APP_ID(Codes.CODE_MISSING, "isv.missing-app-id"),
ISV_MISSING_APP_ID(CodeEnum.MISSING, "isv.missing-app-id"),
/**
* 缺少时间戳参数
*/
ISV_MISSING_TIMESTAMP(Codes.CODE_MISSING, "isv.missing-timestamp"),
ISV_MISSING_TIMESTAMP(CodeEnum.MISSING, "isv.missing-timestamp"),
/**
* 缺少版本参数
*/
ISV_MISSING_VERSION(Codes.CODE_MISSING, "isv.missing-version"),
ISV_MISSING_VERSION(CodeEnum.MISSING, "isv.missing-version"),
/**
* 解密出错, 未指定加密算法
*/
ISV_DECRYPTION_ERROR_MISSING_ENCRYPT_TYPE(Codes.CODE_MISSING, "isv.decryption-error-missing-encrypt-type"),
ISV_DECRYPTION_ERROR_MISSING_ENCRYPT_TYPE(CodeEnum.MISSING, "isv.decryption-error-missing-encrypt-type"),
/**
* 参数无效
*/
ISV_INVALID_PARAMETER(Codes.CODE_INVALID, "isv.invalid-parameter"),
ISV_INVALID_PARAMETER(CodeEnum.INVALID, "isv.invalid-parameter"),
/**
* 参数不正确
*/
ISV_ERROR_PARAMETER(Codes.CODE_INVALID, "isv.error-parameter"),
ISV_ERROR_PARAMETER(CodeEnum.INVALID, "isv.error-parameter"),
/**
* 文件上传失败
*/
ISV_UPLOAD_FAIL(Codes.CODE_INVALID, "isv.upload-fail"),
ISV_UPLOAD_FAIL(CodeEnum.INVALID, "isv.upload-fail"),
/**
* 文件扩展名无效
*/
ISV_INVALID_FILE_EXTENSION(Codes.CODE_INVALID, "isv.invalid-file-extension"),
ISV_INVALID_FILE_EXTENSION(CodeEnum.INVALID, "isv.invalid-file-extension"),
/**
* 文件大小无效
*/
ISV_INVALID_FILE_SIZE(Codes.CODE_INVALID, "isv.invalid-file-size"),
ISV_INVALID_FILE_SIZE(CodeEnum.INVALID, "isv.invalid-file-size"),
/**
* 不存在的方法名
*/
ISV_INVALID_METHOD(Codes.CODE_INVALID, "isv.invalid-method"),
ISV_INVALID_METHOD(CodeEnum.INVALID, "isv.invalid-method"),
/**
* 无效的数据格式
*/
ISV_INVALID_FORMAT(Codes.CODE_INVALID, "isv.invalid-format"),
ISV_INVALID_FORMAT(CodeEnum.INVALID, "isv.invalid-format"),
/**
* 无效的签名类型
*/
ISV_INVALID_SIGNATURE_TYPE(Codes.CODE_INVALID, "isv.invalid-signature-type"),
ISV_INVALID_SIGNATURE_TYPE(CodeEnum.INVALID, "isv.invalid-signature-type"),
/**
* 无效签名
*/
ISV_INVALID_SIGNATURE(Codes.CODE_INVALID, "isv.invalid-signature"),
ISV_INVALID_SIGNATURE(CodeEnum.INVALID, "isv.invalid-signature"),
/**
* 无效的加密类型
*/
ISV_INVALID_ENCRYPT_TYPE(Codes.CODE_INVALID, "isv.invalid-encrypt-type"),
ISV_INVALID_ENCRYPT_TYPE(CodeEnum.INVALID, "isv.invalid-encrypt-type"),
/**
* 解密异常
*/
ISV_INVALID_ENCRYPT(Codes.CODE_INVALID, "isv.invalid-encrypt"),
ISV_INVALID_ENCRYPT(CodeEnum.INVALID, "isv.invalid-encrypt"),
/**
* 无效的appId参数
*/
ISV_INVALID_APP_ID(Codes.CODE_INVALID, "isv.invalid-app-id"),
ISV_INVALID_APP_ID(CodeEnum.INVALID, "isv.invalid-app-id"),
/**
* 非法的时间戳参数
*/
ISV_INVALID_TIMESTAMP(Codes.CODE_INVALID, "isv.invalid-timestamp"),
ISV_INVALID_TIMESTAMP(CodeEnum.INVALID, "isv.invalid-timestamp"),
/**
* 字符集错误
*/
ISV_INVALID_CHARSET(Codes.CODE_INVALID, "isv.invalid-charset"),
ISV_INVALID_CHARSET(CodeEnum.INVALID, "isv.invalid-charset"),
/**
* 摘要错误
*/
ISV_INVALID_DIGEST(Codes.CODE_INVALID, "isv.invalid-digest"),
ISV_INVALID_DIGEST(CodeEnum.INVALID, "isv.invalid-digest"),
/**
* 解密出错,不支持的加密算法
*/
ISV_DECRYPTION_ERROR_NOT_VALID_ENCRYPT_TYPE(Codes.CODE_INVALID, "isv.decryption-error-not-valid-encrypt-type"),
ISV_DECRYPTION_ERROR_NOT_VALID_ENCRYPT_TYPE(CodeEnum.INVALID, "isv.decryption-error-not-valid-encrypt-type"),
/**
* 解密出错, 未配置加密密钥或加密密钥格式错误
*/
ISV_DECRYPTION_ERROR_NOT_VALID_ENCRYPT_KEY(Codes.CODE_INVALID, "isv.decryption-error-not-valid-encrypt-key"),
ISV_DECRYPTION_ERROR_NOT_VALID_ENCRYPT_KEY(CodeEnum.INVALID, "isv.decryption-error-not-valid-encrypt-key"),
/**
* 解密出错,未知异常
*/
ISV_DECRYPTION_ERROR_UNKNOWN(Codes.CODE_INVALID, "isv.decryption-error-unknown"),
ISV_DECRYPTION_ERROR_UNKNOWN(CodeEnum.INVALID, "isv.decryption-error-unknown"),
/**
* 验签出错, 未配置对应签名算法的公钥或者证书
*/
ISV_MISSING_SIGNATURE_CONFIG(Codes.CODE_INVALID, "isv.missing-signature-config"),
ISV_MISSING_SIGNATURE_CONFIG(CodeEnum.INVALID, "isv.missing-signature-config"),
/**
* 本接口不支持第三方代理调用
*/
ISV_NOT_SUPPORT_APP_AUTH(Codes.CODE_INVALID, "isv.not-support-app-auth"),
ISV_NOT_SUPPORT_APP_AUTH(CodeEnum.INVALID, "isv.not-support-app-auth"),
/**
* 可疑的攻击请求
*/
ISV_SUSPECTED_ATTACK(Codes.CODE_INVALID, "isv.suspected-attack"),
ISV_SUSPECTED_ATTACK(CodeEnum.INVALID, "isv.suspected-attack"),
/**
* 无效的content-type
*/
ISV_INVALID_CONTENT_TYPE(Codes.CODE_INVALID, "isv.invalid-content-type"),
ISV_INVALID_CONTENT_TYPE(CodeEnum.INVALID, "isv.invalid-content-type"),
/**
* 业务处理失败
*/
BIZ_ERROR(Codes.CODE_BIZ, ""),
BIZ_ERROR(CodeEnum.BIZ, "isp.biz-error"),
/**
* 请检查配置的账户是否有当前接口权限
*/
ISV_INSUFFICIENT_ISV_PERMISSIONS(Codes.CODE_ISV_PERM, "isv.insufficient-isv-permissions"),
ISV_INSUFFICIENT_ISV_PERMISSIONS(CodeEnum.ISV_PERM, "isv.insufficient-isv-permissions"),
/**
* 代理的商户没有当前接口权限
*/
ISV_INSUFFICIENT_USER_PERMISSIONS(Codes.CODE_ISV_PERM, "isv.insufficient-user-permissions"),
ISV_INSUFFICIENT_USER_PERMISSIONS(CodeEnum.ISV_PERM, "isv.insufficient-user-permissions"),
/**
* 没有当前接口权限
*/
ISV_ROUTE_NO_PERMISSIONS(Codes.CODE_ISV_PERM, "isv.route-no-permissions"),
ISV_ROUTE_NO_PERMISSIONS(CodeEnum.ISV_PERM, "isv.route-no-permissions"),
/**
* 禁止访问
*/
ISV_ACCESS_FORBIDDEN(Codes.CODE_ISV_PERM, "isv.access-forbidden"),
ISV_ACCESS_FORBIDDEN(CodeEnum.ISV_PERM, "isv.access-forbidden"),
/**
* 禁止IP访问
*/
ISV_IP_FORBIDDEN(Codes.CODE_ISV_PERM, "isv.ip-forbidden");
ISV_IP_FORBIDDEN(CodeEnum.ISV_PERM, "isv.ip-forbidden");
private final ErrorMeta errorMeta;
private final CodeEnum codeEnum;
private final String subCode;
ErrorEnum(String code, String subCode) {
this.errorMeta = new ErrorMeta("open.error_", code, subCode);
ErrorEnum(CodeEnum codeEnum, String subCode) {
this.codeEnum = codeEnum;
this.subCode = subCode;
}
public ErrorMeta getErrorMeta() {
return errorMeta;
public IError getError(Locale locale, Object... params) {
OpenMessage codeMsg = OpenMessageFactory.getMessage(codeEnum, locale, params);
OpenMessage subCodeMsg = OpenMessageFactory.getMessage(this, locale, params);
return new ErrorImpl(
codeMsg.getCode(),
codeMsg.getMsg(),
subCodeMsg.getCode(),
subCodeMsg.getMsg(),
subCodeMsg.getSolution()
);
}
private static class Codes {
public static final String CODE_SUCCESS = "10000";
public static final String CODE_AUTH = "20001";
public static final String CODE_MISSING = "40001";
public static final String CODE_INVALID = "40002";
public static final String CODE_BIZ = "40004";
public static final String CODE_ISV_PERM = "40006";
public static final String CODE_UNKNOWN = "20000";
public String getCode() {
return codeEnum.getConfigKey();
}
@Override
public String getConfigKey() {
return subCode;
}
}

View File

@@ -1,131 +0,0 @@
package com.gitee.sop.gateway.message;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
/**
* 负责构建错误消息
*
* @author 六如
*/
@Slf4j
public final class ErrorFactory {
private static final String ZH = "zh";
private static final String SYS_ERR = "系统错误";
private static final String I18N_OPEN_ERROR = "i18n/open/error";
public static final String UNDERLINE = "_";
private static final Set<String> NO_MODULE_CACHE = new HashSet<>();
private static final List<Locale> LOCALE_LIST = Arrays.asList(Locale.ENGLISH, Locale.SIMPLIFIED_CHINESE);
private ErrorFactory() {
}
/**
* 错误信息的国际化信息
*/
private static MessageSourceAccessor errorMessageSourceAccessor;
/**
* 设置国际化资源信息
*/
public static void initMessageSource(List<String> isvModules) {
HashSet<String> baseNamesSet = new HashSet<>();
baseNamesSet.add(I18N_OPEN_ERROR);
if (!CollectionUtils.isEmpty(isvModules)) {
baseNamesSet.addAll(isvModules);
}
String[] totalBaseNames = baseNamesSet.toArray(new String[0]);
log.info("加载错误码国际化资源:{}", StringUtils.arrayToCommaDelimitedString(totalBaseNames));
ResourceBundleMessageSource bundleMessageSource = new ResourceBundleMessageSource();
bundleMessageSource.setBasenames(totalBaseNames);
MessageSourceAccessor messageSourceAccessor = new MessageSourceAccessor(bundleMessageSource);
setErrorMessageSourceAccessor(messageSourceAccessor);
}
/**
* 通过ErrorMetaLocaleparams构建国际化错误消息
*
* @param errorMeta 错误信息
* @param locale 本地化
* @param params 参数
* @return 如果没有配置国际化消息则直接返回errorMeta中的信息
*/
public static IError getError(ErrorMeta errorMeta, Locale locale, Object... params) {
if (locale == null) {
locale = Locale.SIMPLIFIED_CHINESE;
}
String localeStr = locale.toString();
if (localeStr.startsWith(ZH)) {
locale = Locale.SIMPLIFIED_CHINESE;
}
if (!LOCALE_LIST.contains(locale)) {
locale = Locale.ENGLISH;
}
String key = errorMeta.getModulePrefix() + errorMeta.getCode() + errorMeta.getSubCode() + locale.toString();
Assert.notNull(locale, "未设置Locale");
String modulePrefix = errorMeta.getModulePrefix();
String code = errorMeta.getCode();
// open.error_20000=Service is temporarily unavailable
String msg = getErrorMessage(modulePrefix + code, locale);
String subCode = errorMeta.getSubCode();
// open.error_20000_isp.unknown-error=Service is temporarily unavailable
String subMsg = getErrorMessage(modulePrefix + code + UNDERLINE + subCode, locale, params);
if (ObjectUtils.isEmpty(msg)) {
msg = SYS_ERR;
}
if (ObjectUtils.isEmpty(subMsg)) {
subMsg = SYS_ERR;
}
// solution暂未实现如果要实现可以这样配置
// open.error_20000_isp.unknown-error_solution=Service is temporarily unavailable
// <code>String solution = getErrorMessage(modulePrefix + code + UNDERLINE + subCode + "_solution", locale, params);</code>
return new ErrorImpl(code, msg, subCode, subMsg, null);
}
public static void setErrorMessageSourceAccessor(MessageSourceAccessor errorMessageSourceAccessor) {
ErrorFactory.errorMessageSourceAccessor = errorMessageSourceAccessor;
}
/**
* 返回本地化信息
*
* @param module 错误模块
* @param locale 本地化
* @param params 参数
* @return 返回信息
*/
public static String getErrorMessage(String module, Locale locale, Object... params) {
if (NO_MODULE_CACHE.contains(module)) {
return null;
}
try {
return errorMessageSourceAccessor.getMessage(module, params, locale);
} catch (Exception e) {
NO_MODULE_CACHE.add(module);
return null;
}
}
}

View File

@@ -1,34 +0,0 @@
package com.gitee.sop.gateway.message;
import lombok.Getter;
import java.util.Locale;
/**
* 错误对象
*
* @author 六如
*/
@Getter
public class ErrorMeta {
private final String modulePrefix;
private final String code;
private final String subCode;
public ErrorMeta(String modulePrefix, String code, String subCode) {
this.modulePrefix = modulePrefix;
this.code = code;
this.subCode = subCode;
}
public IError getError(Locale locale, Object... params) {
return ErrorFactory.getError(this, locale, params);
}
@Override
public String toString() {
return modulePrefix + code + "_" + subCode;
}
}

View File

@@ -1,8 +1,6 @@
package com.gitee.sop.gateway.response;
import com.gitee.sop.gateway.exception.ApiException;
import com.gitee.sop.gateway.message.ErrorEnum;
import com.gitee.sop.gateway.message.ErrorMeta;
import com.gitee.sop.gateway.message.IError;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -78,47 +76,43 @@ public class ApiResponse extends BaseResponse {
}
public static ApiResponse error(ApiException e) {
IError error = e.getError();
return error(error);
}
public static ApiResponse error(ErrorEnum errorEnum, Locale locale, String subMsg) {
ErrorMeta errorMeta = errorEnum.getErrorMeta();
IError error = errorMeta.getError(locale);
IError error = errorEnum.getError(locale);
return error(error, subMsg);
}
public static ApiResponse error(ErrorEnum errorEnum, Locale locale, String subCode, String subMsg) {
ErrorMeta errorMeta = errorEnum.getErrorMeta();
IError error = errorMeta.getError(locale);
public static ApiResponse error(ErrorEnum errorEnum, Locale locale, String subCode, String subMsg, String solution) {
IError error = errorEnum.getError(locale);
ApiResponse apiResponse = new ApiResponse();
apiResponse.setCode(error.getCode());
apiResponse.setMsg(error.getMsg());
apiResponse.setSubCode(subCode);
apiResponse.setSubMsg(subMsg);
apiResponse.setSolution(solution);
return apiResponse;
}
public static ApiResponse error(ErrorEnum errorEnum, Locale locale) {
ErrorMeta errorMeta = errorEnum.getErrorMeta();
IError error = errorMeta.getError(locale);
IError error = errorEnum.getError(locale);
return error(error);
}
public static ApiResponse error(IError error) {
return error(error, error.getSubMsg());
}
public static ApiResponse error(IError error, String subMsg) {
ApiResponse apiResponse = new ApiResponse();
apiResponse.setSubCode(error.getSubCode());
apiResponse.setSubMsg(error.getSubMsg());
apiResponse.setCode(error.getCode());
apiResponse.setMsg(subMsg);
apiResponse.setMsg(error.getMsg());
apiResponse.setSolution(error.getSolution());
return apiResponse;
}
private static ApiResponse error(IError error, String subMsg) {
ApiResponse response = error(error);
response.setSubMsg(subMsg);
return response;
}
public Response toLower() {
ApiResponseLower apiResponseLower = new ApiResponseLower();
apiResponseLower.setSub_code(this.subCode);
@@ -126,6 +120,7 @@ public class ApiResponse extends BaseResponse {
apiResponseLower.setCode(this.subCode);
apiResponseLower.setMsg(this.subMsg);
apiResponseLower.setData(this.getData());
apiResponseLower.setSolution(this.getSolution());
return apiResponseLower;
}
}

View File

@@ -2,7 +2,6 @@ package com.gitee.sop.gateway.response;
import com.gitee.sop.gateway.exception.ApiException;
import com.gitee.sop.gateway.message.ErrorEnum;
import com.gitee.sop.gateway.message.ErrorMeta;
import com.gitee.sop.gateway.message.IError;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -84,14 +83,12 @@ public class ApiResponseLower extends BaseResponse {
}
public static ApiResponseLower error(ErrorEnum errorEnum, Locale locale, String subMsg) {
ErrorMeta errorMeta = errorEnum.getErrorMeta();
IError error = errorMeta.getError(locale);
IError error = errorEnum.getError(locale);
return error(error, subMsg);
}
public static ApiResponseLower error(ErrorEnum errorEnum, Locale locale) {
ErrorMeta errorMeta = errorEnum.getErrorMeta();
IError error = errorMeta.getError(locale);
IError error = errorEnum.getError(locale);
return error(error);
}

View File

@@ -26,4 +26,8 @@ public class BaseResponse implements Response {
*/
private Object data;
/**
* 解决方案
*/
private String solution;
}

View File

@@ -6,15 +6,19 @@ import com.gitee.sop.gateway.common.SopConstants;
import com.gitee.sop.gateway.config.ApiConfig;
import com.gitee.sop.gateway.request.ApiRequest;
import com.gitee.sop.gateway.request.ApiRequestContext;
import com.gitee.sop.gateway.request.RequestFormatEnum;
import com.gitee.sop.gateway.request.UploadContext;
import com.gitee.sop.gateway.response.Response;
import com.gitee.sop.gateway.util.JsonUtil;
import com.gitee.sop.gateway.util.RequestUtil;
import com.gitee.sop.gateway.util.ResponseUtil;
import com.gitee.sop.gateway.util.XmlUtil;
import com.gitee.sop.support.dto.FileData;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -39,6 +43,9 @@ public class ParamExecutorImpl implements ParamExecutor<HttpServletRequest, Http
@Autowired
private ApiConfig apiConfig;
@Autowired
private Serde serde;
@Override
public ApiRequestContext build(HttpServletRequest request) {
// get请求可能返回null
@@ -107,6 +114,7 @@ public class ParamExecutorImpl implements ParamExecutor<HttpServletRequest, Http
public void write(ApiRequestContext apiRequestContext, Response apiResponse, HttpServletResponse response) throws IOException {
Object data = apiResponse.getData();
if (data instanceof FileData) {
// 处理文件下载
FileData fileData = (FileData) data;
ResponseUtil.writerFile(fileData, response);
} else {
@@ -115,7 +123,23 @@ public class ParamExecutorImpl implements ParamExecutor<HttpServletRequest, Http
if (!apiResponse.needWrap()) {
responseData = data;
}
ResponseUtil.writerText(apiRequestContext, responseData, response);
this.writerText(apiRequestContext, responseData, response);
}
}
protected void writerText(ApiRequestContext apiRequestContext, Object apiResponse, HttpServletResponse response) throws IOException {
ApiRequest apiRequest = apiRequestContext.getApiRequest();
String charset = apiRequest.getCharset();
response.setCharacterEncoding(charset);
String format = apiRequest.getFormat();
if (RequestFormatEnum.of(format) == RequestFormatEnum.XML) {
response.setContentType(MediaType.APPLICATION_XML_VALUE);
String xml = serde.toXml(apiResponse);
response.getWriter().write(xml);
} else {
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
String json = serde.toJSONString(apiResponse);
response.getWriter().write(json);
}
}
}

View File

@@ -0,0 +1,14 @@
package com.gitee.sop.gateway.service;
/**
* 序列化
*
* @author 六如
*/
public interface Serde {
String toJSONString(Object object);
String toXml(Object object);
}

View File

@@ -0,0 +1,24 @@
package com.gitee.sop.gateway.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.gitee.sop.gateway.util.JsonUtil;
import com.gitee.sop.gateway.util.XmlUtil;
/**
* @author 六如
*/
public class SerdeImpl implements Serde{
@Override
public String toJSONString(Object object) {
return JsonUtil.toJSONString(object);
}
@Override
public String toXml(Object object) {
try {
return XmlUtil.toXml(object);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -5,14 +5,13 @@ import com.gitee.sop.gateway.config.ApiConfig;
import com.gitee.sop.gateway.exception.ApiException;
import com.gitee.sop.gateway.exception.SignException;
import com.gitee.sop.gateway.message.ErrorEnum;
import com.gitee.sop.gateway.message.ErrorMeta;
import com.gitee.sop.gateway.request.ApiRequest;
import com.gitee.sop.gateway.request.ApiRequestContext;
import com.gitee.sop.gateway.service.validate.Signer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.HashMap;
import java.util.Map;
@@ -46,9 +45,8 @@ public class AlipaySigner implements Signer {
return AlipaySignature.rsaCheckV2(params, publicKey, charset, signType, apiConfig);
} catch (SignException e) {
ErrorEnum errorEnum = e.getErrorEnum();
ErrorMeta errorMeta = errorEnum.getErrorMeta();
log.error("验签错误, code={}, subCode={}, apiRequest={}",
errorMeta.getCode(), errorMeta.getSubCode(), apiRequest, e);
errorEnum.getCode(), errorEnum.getSubCode(), apiRequest, e);
throw new ApiException(errorEnum, apiRequestContext.getLocale());
} catch (Exception e) {
log.error("验签未知错误, apiRequest={}", apiRequest, e);

View File

@@ -0,0 +1,7 @@
0=Success
20001=Insufficient authorization authority
40001=Missing required parameters
40002=Invalid parameter
50003=Business error
40006=Insufficient permissions
99999=Service unavailable

View File

@@ -0,0 +1,7 @@
0=Success
20001=\u6388\u6743\u6743\u9650\u4E0D\u8DB3
40001=\u7F3A\u5C11\u5FC5\u9009\u53C2\u6570
40002=\u975E\u6CD5\u7684\u53C2\u6570
50003=\u4E1A\u52A1\u5904\u7406\u5931\u8D25
40006=\u6743\u9650\u4E0D\u8DB3
99999=\u670D\u52A1\u4E0D\u53EF\u7528

View File

@@ -1,65 +1,51 @@
# \u7F51\u5173\u9519\u8BEF\u914D\u7F6E
isp.unknown-error=Service is temporarily unavailable
isp.service-unknown-error=Service not available
isp.service-not-available=Service is temporarily unavailable
isp.gateway-response-timeout=Gateway response timeout
isp.biz-error=Business error
isv.service-busy=service busy
open.error_10000=Success
aop.invalid-auth-token=Invalid access token
aop.auth-token-time-out=The access token has expired
aop.invalid-app-auth-token=Invalid application authorization token
aop.invalid-app-auth-token-no-api=Merchant does not authorize current interface
aop.app-auth-token-time-out=The application authorization token has expired
aop.no-product-reg-by-partner=The merchant has not signed any product
# \u683C\u5F0F\uFF1A\u524D\u7F00 + \u7F51\u5173\u9519\u8BEF\u7801 + "_"+ \u5B50\u9519\u8BEF\u7801
# open.error_\uFF08\u524D\u7F00\uFF0920000\uFF08\u7F51\u5173\u9519\u8BEF\u7801\uFF09_isp.unknow-error\uFF08\u5B50\u9519\u8BEF\u7801\uFF09
open.error_20000=Service is temporarily unavailable
open.error_20000_isp.unknown-error=Service is temporarily unavailable
open.error_20000_isp.service-unknown-error=Service not available
open.error_20000_aop.unknown-error=Service is temporarily unavailable
open.error_20000_isp.service-not-available=Service is temporarily unavailable
open.error_20000_isp.gateway-response-timeout=Gateway response timeout
open.error_20000_isv.service-busy=service busy
isv.missing-method=Method name parameter is missing
isv.missing-signature=Lack of signature parameter
isv.missing-signature-type=Missing signature type parameter
isv.missing-signature-key=Lack of signature configuration
isv.missing-app-id=Missing appId parameter
isv.missing-timestamp=Missing timestamp parameter
isv.missing-version=Missing version parameter
isv.decryption-error-missing-encrypt-type=Decryption error, no encryption algorithm specified
open.error_20001=Insufficient authorization authority
open.error_20001_aop.invalid-auth-token=Invalid access token
open.error_20001_aop.auth-token-time-out=The access token has expired
open.error_20001_aop.invalid-app-auth-token=Invalid application authorization token
open.error_20001_aop.invalid-app-auth-token-no-api=Merchant does not authorize current interface
open.error_20001_aop.app-auth-token-time-out=The application authorization token has expired
open.error_20001_aop.no-product-reg-by-partner=The merchant has not signed any product
isv.invalid-parameter=Parameter is invalid
isv.error-parameter=Parameter incorrect
isv.upload-fail=File upload failed
isv.invalid-file-extension=Invalid file extension
isv.invalid-file-size=Invalid {0} bytes file size, the limit max size is {1} bytes
isv.invalid-method=Nonexistent method name
isv.invalid-format=Invalid data format
isv.invalid-signature-type=Invalid signature type
isv.invalid-signature=Invalid signature
isv.invalid-encrypt-type=Invalid encryption type
isv.invalid-encrypt=Decryption exception
isv.invalid-app-id=Invalid appId parameter
isv.invalid-timestamp=Invalid timestamp parameter
isv.invalid-charset=Character set error
isv.invalid-digest=Digest error
isv.decryption-error-not-valid-encrypt-type=Decryption error, unsupported encryption algorithm
isv.decryption-error-not-valid-encrypt-key=Decryption error, unconfigured encryption key or encryption key format error
isv.decryption-error-unknown=Decryption error, unknown exception
isv.missing-signature-config=Signature verification error, no public key or certificate of the corresponding signature algorithm is configured
isv.not-support-app-auth=This interface does not support third-party proxy calls
isv.suspected-attack=Suspicious attack requests
isv.invalid-content-type=Invalid content type
open.error_40001=Missing required parameters
open.error_40001_isv.missing-method=Method name parameter is missing
open.error_40001_isv.missing-signature=Lack of signature parameter
open.error_40001_isv.missing-signature-type=Missing signature type parameter
open.error_40001_isv.missing-signature-key=Lack of signature configuration
open.error_40001_isv.missing-app-id=Missing appId parameter
open.error_40001_isv.missing-timestamp=Missing timestamp parameter
open.error_40001_isv.missing-version=Missing version parameter
open.error_40001_isv.decryption-error-missing-encrypt-type=Decryption error, no encryption algorithm specified
open.error_40002=Invalid parameter
open.error_40002_isv.invalid-parameter=Parameter is invalid
open.error_40002_isv.error-parameter=Parameter incorrect
open.error_40002_isv.upload-fail=File upload failed
open.error_40002_isv.invalid-file-extension=Invalid file extension
open.error_40002_isv.invalid-file-size=Invalid {0} bytes file size, the limit max size is {1} bytes
open.error_40002_isv.invalid-method=Nonexistent method name
open.error_40002_isv.invalid-format=Invalid data format
open.error_40002_isv.invalid-signature-type=Invalid signature type
open.error_40002_isv.invalid-signature=Invalid signature
open.error_40002_isv.invalid-encrypt-type=Invalid encryption type
open.error_40002_isv.invalid-encrypt=Decryption exception
open.error_40002_isv.invalid-app-id=Invalid appId parameter
open.error_40002_isv.invalid-timestamp=Invalid timestamp parameter
open.error_40002_isv.invalid-charset=Character set error
open.error_40002_isv.invalid-digest=Digest error
open.error_40002_isv.decryption-error-not-valid-encrypt-type=Decryption error, unsupported encryption algorithm
open.error_40002_isv.decryption-error-not-valid-encrypt-key=Decryption error, unconfigured encryption key or encryption key format error
open.error_40002_isv.decryption-error-unknown=Decryption error, unknown exception
open.error_40002_isv.missing-signature-config=Signature verification error, no public key or certificate of the corresponding signature algorithm is configured
open.error_40002_isv.not-support-app-auth=This interface does not support third-party proxy calls
open.error_40002_isv.suspected-attack=Suspicious attack requests
open.error_40002_isv.invalid-content-type=Invalid content type
open.error_40004=Business processing failure
open.error_40004_=Business processing failure
open.error_40006=Insufficient permissions
open.error_40006_isv.insufficient-isv-permissions=Insufficient ISV permissions
open.error_40006_isv.insufficient-user-permissions=Insufficient user permissions
open.error_40006_isv.route-no-permissions=No api permissions
open.error_40006_isv.access-forbidden=Access forbidden
open.error_40006_isv.ip-forbidden=IP access forbidden
isv.insufficient-isv-permissions=Insufficient ISV permissions
isv.insufficient-user-permissions=Insufficient user permissions
isv.route-no-permissions=No api permissions
isv.access-forbidden=Access forbidden
isv.ip-forbidden=IP access forbidden

View File

@@ -1,122 +1,51 @@
# \u7F51\u5173\u9519\u8BEF\u914D\u7F6E
isp.unknown-error=\u670D\u52A1\u6682\u4E0D\u53EF\u7528
isp.service-unknown-error=\u670D\u52A1\u4E0D\u53EF\u7528
isp.service-not-available=\u670D\u52A1\u6682\u4E0D\u53EF\u7528
isp.gateway-response-timeout=\u7F51\u5173\u54CD\u5E94\u8D85\u65F6
isp.biz-error=\u4e1a\u52a1\u5f02\u5e38
isv.service-busy=\u670D\u52A1\u5668\u5FD9
#open.error_20000=\u670D\u52A1\u4E0D\u53EF\u7528
#open.error_20000_isp.unknow-error=\u670D\u52A1\u6682\u4E0D\u53EF\u7528
#open.error_20000_aop.unknow-error=\u670D\u52A1\u6682\u4E0D\u53EF\u7528
#open.error_20000_isp.service-not-available=\u670D\u52A1\u6682\u4E0D\u53EF\u7528
#
#open.error_20001=\u6388\u6743\u6743\u9650\u4E0D\u8DB3
#open.error_20001_aop.invalid-auth-token=\u65E0\u6548\u7684\u8BBF\u95EE\u4EE4\u724C
#open.error_20001_aop.auth-token-time-out=\u8BBF\u95EE\u4EE4\u724C\u5DF2\u8FC7\u671F
#open.error_20001_aop.invalid-app-auth-token=\u65E0\u6548\u7684\u5E94\u7528\u6388\u6743\u4EE4\u724C
#open.error_20001_aop.invalid-app-auth-token-no-api=\u5546\u6237\u672A\u6388\u6743\u5F53\u524D\u63A5\u53E3
#open.error_20001_aop.app-auth-token-time-out=\u5E94\u7528\u6388\u6743\u4EE4\u724C\u5DF2\u8FC7\u671F
#open.error_20001_aop.no-product-reg-by-partner=\u5546\u6237\u672A\u7B7E\u7EA6\u4EFB\u4F55\u4EA7\u54C1
#
#open.error_40001=\u7F3A\u5C11\u5FC5\u9009\u53C2\u6570
#open.error_40001_isv.missing-method=\u7F3A\u5C11\u65B9\u6CD5\u540D\u53C2\u6570
#open.error_40001_isv.missing-signature=\u7F3A\u5C11\u7B7E\u540D\u53C2\u6570
#open.error_40001_isv.missing-signature-type=\u7F3A\u5C11\u7B7E\u540D\u7C7B\u578B\u53C2\u6570
#open.error_40001_isv.missing-signature-key=\u7F3A\u5C11\u7B7E\u540D\u914D\u7F6E
#open.error_40001_isv.missing-app-id=\u7F3A\u5C11appId\u53C2\u6570
#open.error_40001_isv.missing-timestamp=\u7F3A\u5C11\u65F6\u95F4\u6233\u53C2\u6570
#open.error_40001_isv.missing-version=\u7F3A\u5C11\u7248\u672C\u53C2\u6570
#open.error_40001_isv.decryption-error-missing-encrypt-type=\u89E3\u5BC6\u51FA\u9519, \u672A\u6307\u5B9A\u52A0\u5BC6\u7B97\u6CD5
#
#open.error_40002=\u975E\u6CD5\u7684\u53C2\u6570
#open.error_40002_isv.invalid-parameter=\u53C2\u6570\u65E0\u6548
#open.error_40002_isv.upload-fail=\u6587\u4EF6\u4E0A\u4F20\u5931\u8D25
#open.error_40002_isv.invalid-file-extension=\u6587\u4EF6\u6269\u5C55\u540D\u65E0\u6548
#open.error_40002_isv.invalid-file-size={0}\u6587\u4EF6\u5927\u5C0F\u65E0\u6548\uFF0C\u5355\u6587\u4EF6\u4E0D\u5F97\u8D85\u8FC7{1}
#open.error_40002_isv.invalid-method=\u4E0D\u5B58\u5728\u7684\u65B9\u6CD5\u540D
#open.error_40002_isv.invalid-format=\u65E0\u6548\u7684\u6570\u636E\u683C\u5F0F
#open.error_40002_isv.invalid-signature-type=\u65E0\u6548\u7684\u7B7E\u540D\u7C7B\u578B
#open.error_40002_isv.invalid-signature=\u65E0\u6548\u7B7E\u540D
#open.error_40002_isv.invalid-encrypt-type=\u65E0\u6548\u7684\u52A0\u5BC6\u7C7B\u578B
#open.error_40002_isv.invalid-encrypt=\u89E3\u5BC6\u5F02\u5E38
#open.error_40002_isv.invalid-app-id=\u65E0\u6548\u7684appId\u53C2\u6570
#open.error_40002_isv.invalid-timestamp=\u975E\u6CD5\u7684\u65F6\u95F4\u6233\u53C2\u6570
#open.error_40002_isv.invalid-charset=\u5B57\u7B26\u96C6\u9519\u8BEF
#open.error_40002_isv.invalid-digest=\u6458\u8981\u9519\u8BEF
#open.error_40002_isv.decryption-error-not-valid-encrypt-type=\u89E3\u5BC6\u51FA\u9519\uFF0C\u4E0D\u652F\u6301\u7684\u52A0\u5BC6\u7B97\u6CD5
#open.error_40002_isv.decryption-error-not-valid-encrypt-key=\u89E3\u5BC6\u51FA\u9519, \u672A\u914D\u7F6E\u52A0\u5BC6\u5BC6\u94A5\u6216\u52A0\u5BC6\u5BC6\u94A5\u683C\u5F0F\u9519\u8BEF
#open.error_40002_isv.decryption-error-unknown=\u89E3\u5BC6\u51FA\u9519\uFF0C\u672A\u77E5\u5F02\u5E38
#open.error_40002_isv.missing-signature-config=\u9A8C\u7B7E\u51FA\u9519, \u672A\u914D\u7F6E\u5BF9\u5E94\u7B7E\u540D\u7B97\u6CD5\u7684\u516C\u94A5\u6216\u8005\u8BC1\u4E66
#open.error_40002_isv.not-support-app-auth=\u672C\u63A5\u53E3\u4E0D\u652F\u6301\u7B2C\u4E09\u65B9\u4EE3\u7406\u8C03\u7528
#open.error_40002_isv.suspected-attack=\u53EF\u7591\u7684\u653B\u51FB\u8BF7\u6C42
#open.error_40002_isv.invalid-content-type=\u65E0\u6548\u7684content-type
#
#open.error_40004=\u4E1A\u52A1\u5904\u7406\u5931\u8D25
#open.error_40004_=\u4E1A\u52A1\u5904\u7406\u5931\u8D25
#
#open.error_40006=\u6743\u9650\u4E0D\u8DB3
#open.error_40006_isv.insufficient-isv-permissions=\u8BF7\u68C0\u67E5\u914D\u7F6E\u7684\u8D26\u6237\u662F\u5426\u6709\u5F53\u524D\u63A5\u53E3\u6743\u9650
#open.error_40006_isv.insufficient-user-permissions=\u4EE3\u7406\u7684\u5546\u6237\u6CA1\u6709\u5F53\u524D\u63A5\u53E3\u6743\u9650
#open.error_40006_isv.route-no-permissions=\u6CA1\u6709\u5F53\u524D\u63A5\u53E3\u6743\u9650
#open.error_40006_isv.access-forbidden=\u65E0\u6743\u8BBF\u95EE
aop.invalid-auth-token=\u65E0\u6548\u7684\u8BBF\u95EE\u4EE4\u724C
aop.auth-token-time-out=\u8BBF\u95EE\u4EE4\u724C\u5DF2\u8FC7\u671F
aop.invalid-app-auth-token=\u65E0\u6548\u7684\u5E94\u7528\u6388\u6743\u4EE4\u724C
aop.invalid-app-auth-token-no-api=\u5546\u6237\u672A\u6388\u6743\u5F53\u524D\u63A5\u53E3
aop.app-auth-token-time-out=\u5E94\u7528\u6388\u6743\u4EE4\u724C\u5DF2\u8FC7\u671F
aop.no-product-reg-by-partner=\u5546\u6237\u672A\u7B7E\u7EA6\u4EFB\u4F55\u4EA7\u54C1
isv.missing-method=\u7F3A\u5C11\u65B9\u6CD5\u540D\u53C2\u6570
isv.missing-signature=\u7F3A\u5C11\u7B7E\u540D\u53C2\u6570
isv.missing-signature-type=\u7F3A\u5C11\u7B7E\u540D\u7C7B\u578B\u53C2\u6570
isv.missing-signature-key=\u7F3A\u5C11\u7B7E\u540D\u914D\u7F6E
isv.missing-app-id=\u7F3A\u5C11 appId \u53C2\u6570
isv.missing-timestamp=\u7F3A\u5C11\u65F6\u95F4\u6233\u53C2\u6570
isv.missing-version=\u7F3A\u5C11\u7248\u672C\u53C2\u6570
isv.decryption-error-missing-encrypt-type=\u89E3\u5BC6\u51FA\u9519, \u672A\u6307\u5B9A\u52A0\u5BC6\u7B97\u6CD5
open.error_10000=Success
isv.invalid-parameter=\u53C2\u6570\u65E0\u6548
isv.error-parameter=\u53c2\u6570\u4e0d\u6b63\u786e
isv.upload-fail=\u6587\u4EF6\u4E0A\u4F20\u5931\u8D25
isv.invalid-file-extension=\u6587\u4EF6\u6269\u5C55\u540D\u65E0\u6548
isv.invalid-file-size={0}\u6587\u4EF6\u5927\u5C0F\u65E0\u6548\uFF0C\u5355\u6587\u4EF6\u4E0D\u5F97\u8D85\u8FC7{1}
isv.invalid-method=\u4E0D\u5B58\u5728\u7684\u65B9\u6CD5\u540D
isv.invalid-format=\u65E0\u6548\u7684\u6570\u636E\u683C\u5F0F
isv.invalid-signature-type=\u65E0\u6548\u7684\u7B7E\u540D\u7C7B\u578B
isv.invalid-signature=\u65E0\u6548\u7B7E\u540D
isv.invalid-encrypt-type=\u65E0\u6548\u7684\u52A0\u5BC6\u7C7B\u578B
isv.invalid-encrypt=\u89E3\u5BC6\u5F02\u5E38
isv.invalid-app-id=\u65E0\u6548\u7684 appId \u53C2\u6570
isv.invalid-timestamp=\u975E\u6CD5\u7684\u65F6\u95F4\u6233\u53C2\u6570
isv.invalid-charset=\u5B57\u7B26\u96C6\u9519\u8BEF
isv.invalid-digest=\u6458\u8981\u9519\u8BEF
isv.decryption-error-not-valid-encrypt-type=\u89E3\u5BC6\u51FA\u9519\uFF0C\u4E0D\u652F\u6301\u7684\u52A0\u5BC6\u7B97\u6CD5
isv.decryption-error-not-valid-encrypt-key=\u89E3\u5BC6\u51FA\u9519, \u672A\u914D\u7F6E\u52A0\u5BC6\u5BC6\u94A5\u6216\u52A0\u5BC6\u5BC6\u94A5\u683C\u5F0F\u9519\u8BEF
isv.decryption-error-unknown=\u89E3\u5BC6\u51FA\u9519\uFF0C\u672A\u77E5\u5F02\u5E38
isv.missing-signature-config=\u9A8C\u7B7E\u51FA\u9519, \u672A\u914D\u7F6E\u5BF9\u5E94\u7B7E\u540D\u7B97\u6CD5\u7684\u516C\u94A5\u6216\u8005\u8BC1\u4E66
isv.not-support-app-auth=\u672C\u63A5\u53E3\u4E0D\u652F\u6301\u7B2C\u4E09\u65B9\u4EE3\u7406\u8C03\u7528
isv.suspected-attack=\u53EF\u7591\u7684\u653B\u51FB\u8BF7\u6C42
isv.invalid-content-type=\u65E0\u6548\u7684 content-type
# \u683C\u5F0F\uFF1A\u524D\u7F00 + \u7F51\u5173\u9519\u8BEF\u7801 + "_"+ \u5B50\u9519\u8BEF\u7801
# open.error_\uFF08\u524D\u7F00\uFF0920000\uFF08\u7F51\u5173\u9519\u8BEF\u7801\uFF09_isp.unknow-error\uFF08\u5B50\u9519\u8BEF\u7801\uFF09
open.error_20000=\u670D\u52A1\u4E0D\u53EF\u7528
open.error_20000_isp.unknown-error=\u670D\u52A1\u6682\u4E0D\u53EF\u7528
open.error_20000_isp.service-unknown-error=\u670D\u52A1\u4E0D\u53EF\u7528
open.error_20000_aop.unknown-error=\u670D\u52A1\u6682\u4E0D\u53EF\u7528
open.error_20000_isp.service-not-available=\u670D\u52A1\u6682\u4E0D\u53EF\u7528
open.error_20000_isp.gateway-response-timeout=\u7F51\u5173\u54CD\u5E94\u8D85\u65F6
open.error_20000_isv.service-busy=\u670D\u52A1\u5668\u5FD9
open.error_20001=\u6388\u6743\u6743\u9650\u4E0D\u8DB3
open.error_20001_aop.invalid-auth-token=\u65E0\u6548\u7684\u8BBF\u95EE\u4EE4\u724C
open.error_20001_aop.auth-token-time-out=\u8BBF\u95EE\u4EE4\u724C\u5DF2\u8FC7\u671F
open.error_20001_aop.invalid-app-auth-token=\u65E0\u6548\u7684\u5E94\u7528\u6388\u6743\u4EE4\u724C
open.error_20001_aop.invalid-app-auth-token-no-api=\u5546\u6237\u672A\u6388\u6743\u5F53\u524D\u63A5\u53E3
open.error_20001_aop.app-auth-token-time-out=\u5E94\u7528\u6388\u6743\u4EE4\u724C\u5DF2\u8FC7\u671F
open.error_20001_aop.no-product-reg-by-partner=\u5546\u6237\u672A\u7B7E\u7EA6\u4EFB\u4F55\u4EA7\u54C1
open.error_40001=\u7F3A\u5C11\u5FC5\u9009\u53C2\u6570
open.error_40001_isv.missing-method=\u7F3A\u5C11\u65B9\u6CD5\u540D\u53C2\u6570
open.error_40001_isv.missing-signature=\u7F3A\u5C11\u7B7E\u540D\u53C2\u6570
open.error_40001_isv.missing-signature-type=\u7F3A\u5C11\u7B7E\u540D\u7C7B\u578B\u53C2\u6570
open.error_40001_isv.missing-signature-key=\u7F3A\u5C11\u7B7E\u540D\u914D\u7F6E
open.error_40001_isv.missing-app-id=\u7F3A\u5C11appId\u53C2\u6570
open.error_40001_isv.missing-timestamp=\u7F3A\u5C11\u65F6\u95F4\u6233\u53C2\u6570
open.error_40001_isv.missing-version=\u7F3A\u5C11\u7248\u672C\u53C2\u6570
open.error_40001_isv.decryption-error-missing-encrypt-type=\u89E3\u5BC6\u51FA\u9519, \u672A\u6307\u5B9A\u52A0\u5BC6\u7B97\u6CD5
open.error_40002=\u975E\u6CD5\u7684\u53C2\u6570
open.error_40002_isv.invalid-parameter=\u53C2\u6570\u65E0\u6548
open.error_40002_isv.error-parameter=\u53c2\u6570\u4e0d\u6b63\u786e
open.error_40002_isv.upload-fail=\u6587\u4EF6\u4E0A\u4F20\u5931\u8D25
open.error_40002_isv.invalid-file-extension=\u6587\u4EF6\u6269\u5C55\u540D\u65E0\u6548
open.error_40002_isv.invalid-file-size={0}\u6587\u4EF6\u5927\u5C0F\u65E0\u6548\uFF0C\u5355\u6587\u4EF6\u4E0D\u5F97\u8D85\u8FC7{1}
open.error_40002_isv.invalid-method=\u4E0D\u5B58\u5728\u7684\u65B9\u6CD5\u540D
open.error_40002_isv.invalid-format=\u65E0\u6548\u7684\u6570\u636E\u683C\u5F0F
open.error_40002_isv.invalid-signature-type=\u65E0\u6548\u7684\u7B7E\u540D\u7C7B\u578B
open.error_40002_isv.invalid-signature=\u65E0\u6548\u7B7E\u540D
open.error_40002_isv.invalid-encrypt-type=\u65E0\u6548\u7684\u52A0\u5BC6\u7C7B\u578B
open.error_40002_isv.invalid-encrypt=\u89E3\u5BC6\u5F02\u5E38
open.error_40002_isv.invalid-app-id=\u65E0\u6548\u7684appId\u53C2\u6570
open.error_40002_isv.invalid-timestamp=\u975E\u6CD5\u7684\u65F6\u95F4\u6233\u53C2\u6570
open.error_40002_isv.invalid-charset=\u5B57\u7B26\u96C6\u9519\u8BEF
open.error_40002_isv.invalid-digest=\u6458\u8981\u9519\u8BEF
open.error_40002_isv.decryption-error-not-valid-encrypt-type=\u89E3\u5BC6\u51FA\u9519\uFF0C\u4E0D\u652F\u6301\u7684\u52A0\u5BC6\u7B97\u6CD5
open.error_40002_isv.decryption-error-not-valid-encrypt-key=\u89E3\u5BC6\u51FA\u9519, \u672A\u914D\u7F6E\u52A0\u5BC6\u5BC6\u94A5\u6216\u52A0\u5BC6\u5BC6\u94A5\u683C\u5F0F\u9519\u8BEF
open.error_40002_isv.decryption-error-unknown=\u89E3\u5BC6\u51FA\u9519\uFF0C\u672A\u77E5\u5F02\u5E38
open.error_40002_isv.missing-signature-config=\u9A8C\u7B7E\u51FA\u9519, \u672A\u914D\u7F6E\u5BF9\u5E94\u7B7E\u540D\u7B97\u6CD5\u7684\u516C\u94A5\u6216\u8005\u8BC1\u4E66
open.error_40002_isv.not-support-app-auth=\u672C\u63A5\u53E3\u4E0D\u652F\u6301\u7B2C\u4E09\u65B9\u4EE3\u7406\u8C03\u7528
open.error_40002_isv.suspected-attack=\u53EF\u7591\u7684\u653B\u51FB\u8BF7\u6C42
open.error_40002_isv.invalid-content-type=\u65E0\u6548\u7684content-type
open.error_40004=\u4E1A\u52A1\u5904\u7406\u5931\u8D25
open.error_40004_=\u4E1A\u52A1\u5904\u7406\u5931\u8D25
open.error_40006=\u6743\u9650\u4E0D\u8DB3
open.error_40006_isv.insufficient-isv-permissions=\u8BF7\u68C0\u67E5\u914D\u7F6E\u7684\u8D26\u6237\u662F\u5426\u6709\u5F53\u524D\u63A5\u53E3\u6743\u9650
open.error_40006_isv.insufficient-user-permissions=\u4EE3\u7406\u7684\u5546\u6237\u6CA1\u6709\u5F53\u524D\u63A5\u53E3\u6743\u9650
open.error_40006_isv.route-no-permissions=\u6CA1\u6709\u5F53\u524D\u63A5\u53E3\u6743\u9650
open.error_40006_isv.access-forbidden=\u65E0\u6743\u8BBF\u95EE
open.error_40006_isv.ip-forbidden=IP\u65E0\u6743\u8BBF\u95EE
isv.insufficient-isv-permissions=\u8BF7\u68C0\u67E5\u914D\u7F6E\u7684\u8D26\u6237\u662F\u5426\u6709\u5F53\u524D\u63A5\u53E3\u6743\u9650
isv.insufficient-user-permissions=\u4EE3\u7406\u7684\u5546\u6237\u6CA1\u6709\u5F53\u524D\u63A5\u53E3\u6743\u9650
isv.route-no-permissions=\u6CA1\u6709\u5F53\u524D\u63A5\u53E3\u6743\u9650
isv.access-forbidden=\u65E0\u6743\u8BBF\u95EE
isv.ip-forbidden=IP\u65E0\u6743\u8BBF\u95EE

View File

@@ -1 +0,0 @@
存放国际化文件