服务器错误码国际化

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

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

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.

 

posted on 2019-10-21 16:49  swave  阅读(1080)  评论(0编辑  收藏  举报

导航