zoukankan      html  css  js  c++  java
  • 服务器错误码国际化

    最近项目要做国际化,由于前端直接显示了后端返回的错误码文案,所以后端需要针对错误码做国际化。

    实现过程中主要考虑要满足以下两个需求:

    1、由于世界的语言非常多,所以新增一门语言能够快速增加,不需要改动代码骨架。

    2、在新增一个错误码时,不同的语言的实现类都要同步新增一个错误码,如果未新增时,系统启动时应该给于提示/报错.

    基于以上两个需求,想到用工厂模式来实现该需求,实现过程主要包括以下几个类:

    LanguageErrorCodeService:语言相关错误码业务接口。

    AbstractLanguageErrorCodeService:抽象语言相关错误码业务接口实现类。

    LangErrorCodeFactory:语言错误码工厂类 ,主要作用是通过语言去获得对应的处理业务类。

    ErrorCodeEnum:错误码枚举,全部语言的错误码都基于这个枚举去定义翻译后的错误码文案。

    ChinaErrorCodeService、EngishErrorCodeService、GermanErrorCodeService:具体语言实现业务类

    代码结构:

    以下为具体的实现代码:

    public interface LanguageErrorCodeService {
    
        /**
         * 
         * @param errorCode 错误枚举
         * @return 错误码文案
         */
        String getMessage(ErrorCodeEnum errorCode);
    }
    public abstract class AbstractLanguageErrorCodeService implements LanguageErrorCodeService,InitializingBean{
        
        
        @Override
        public void afterPropertiesSet() throws Exception {
            //校验子类中定义的错误码是否足够,避免每次定义新的错误码之后,子类忘记定义的漏洞
            //如果子类的错误码未配置全,那么启动进程时将报错。
            ErrorCodeEnum[] enums = ErrorCodeEnum.values();
            for(ErrorCodeEnum errorCode :  enums) {
                if (!hasErrorCode(errorCode)) {
                    throw new IllegalStateException(this.getClass().getSimpleName()+"缺少配置的国际化错误msg");
                }
            }
            
        }
    
        /**
         * 是否有错误码
         * @param errorCode
         * @return
         */
        protected abstract boolean hasErrorCode(ErrorCodeEnum errorCode);
    
    }
    @Component
    public class LangErrorCodeFactory implements ApplicationContextAware{
        
        private ApplicationContext applicationContext;
        
        /**
         * 错误代码语言类
         * @param language 语言
         * @return
         */
        public LanguageErrorCodeService getLangErrorCode(String language) {
            return applicationContext.getBean(language, LanguageErrorCodeService.class);
        }
        
        public String[] getAllService(){
            return applicationContext.getBeanNamesForType(LanguageErrorCodeService.class);
        }
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            this.applicationContext = applicationContext;
        }
        
        
        public static void main(String[] args) {
            ApplicationContext application = new AnnotationConfigApplicationContext("org.zhanglang.test.web.errorcode");
            LangErrorCodeFactory langErrorCodeFactory = application.getBean(LangErrorCodeFactory.class);
            ErrorCodeEnum passwordError = ErrorCodeEnum.PASSWORD_ERROR;
            for (String service : langErrorCodeFactory.getAllService()) {
                String msg = ((LanguageErrorCodeService)application.getBean(service)).getMessage(passwordError);
                System.out.println(service+"'s errormsg is "+msg);
            }
        }
    
    }
    public enum ErrorCodeEnum {
        
        SUCCESS("0","成功"),
        PASSWORD_ERROR("001","密码错误"),
        OUT_OF_RETAY_TIMES("002","超过登录最大尝试次数"),
        CHANGE_DEVICE("003","更换了设备?");
    
        private ErrorCodeEnum(String code, String message) {
            this.code = code;
            this.message = message;
        }
    
        private String code;
        
        private String message;
    
        public String getCode() {
            return code;
        }
    
        public String getMessage() {
            return message;
        }
        
    }
    @Service("cn")
    public class ChinaErrorCodeService extends AbstractLanguageErrorCodeService implements LanguageErrorCodeService {
        
        @Override
        public String getMessage(ErrorCodeEnum errorCode) {
            return errorCode.getMessage();
        }
    
        @Override
        protected boolean hasErrorCode(ErrorCodeEnum errorCode) {
            return true;
        }
    }
    @Service("engish")
    public class EngishErrorCodeService extends AbstractLanguageErrorCodeService implements LanguageErrorCodeService {
    
        private static final Map<ErrorCodeEnum,String> codeMap = new HashMap<>();
        
        static {
            codeMap.put(ErrorCodeEnum.SUCCESS, "success.");
            codeMap.put(ErrorCodeEnum.CHANGE_DEVICE,"change device." );
            codeMap.put(ErrorCodeEnum.OUT_OF_RETAY_TIMES,"out of retry times." );
            codeMap.put(ErrorCodeEnum.PASSWORD_ERROR, "password is error.");
            
        }
        
        @Override
        public String getMessage(ErrorCodeEnum errorCode) {
            String msg = codeMap.get(errorCode);
            return msg;
        }
    
        @Override
        protected boolean hasErrorCode(ErrorCodeEnum errorCode) {
            return codeMap.containsKey(errorCode);
        }
    
    
    }

    运行LangErrorCodeFactory中的main方法,控制台打印出以下结果,ok.

    1234 [main] INFO  o.s.c.a.AnnotationConfigApplicationContext - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@157632c9: startup date [Mon Oct 21 16:48:13 CST 2019]; root of context hierarchy
    1399 [main] INFO  o.s.b.f.a.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
    cn's errormsg is 密码错误
    engish's errormsg is password is error.
    german's errormsg is Fehler beim Passwort.
  • 相关阅读:
    数据库复习之数据库系统概论
    C++前缀表达式和后缀表达式
    MySQL——排序和分页
    MySQL——联表查询
    MySQL——Where条件子句
    MySQL——DQL查询数据(Select)
    MySQL——外键、DML语言(添加、修改、删除)
    MySQL——数据库的操作、属性
    MySQL——简介和安装
    MySQL——数据库
  • 原文地址:https://www.cnblogs.com/swave/p/11714480.html
Copyright © 2011-2022 走看看