`
xpp02
  • 浏览: 1013295 次
社区版块
存档分类
最新评论

业务层资源国际化处理

阅读更多

 

用过struts2等mvc框架开发的同学都知道,使用struts2处理国际化的消息非常简单直观,但是mvc框架的定位是在展示层(jsp,action)等,在一个典型的3层结构中,处于最上层的位置,按照分层设计原则,下层组件是不可以调用上层组件的,这样就存在一个问题,我们在业务层中可能也会出现一些需要国际化处理的消息信息,这些信息如何设置呢?

     在这篇文章中,我们将借鉴struts2的国际化处理机制,但是要比struts2简单的多,因为业务层需要国际化处理的消息毕竟是少数,废话不多说,直接上干货

先举个例子-业务层未国际化处理前的代码

 

  1. @Override  
  2.   public ExecuteResult<User> login(String userName, String password) {  
  3.       ExecuteResult<User> executeResult = new ExecuteResult<User>();  
  4.       User userInfo = userDAO.getUserByName(userName);  
  5.       if(userInfo == null){  
  6.           executeResult.addErrorMessage("不存在的用户名");  
  7.           return executeResult;  
  8.       }  
  9.       if(!userInfo.getPassword().equals(password)){  
  10.           executeResult.addErrorMessage("密码错误");  
  11.           return executeResult;  
  12.       }  
  13.       executeResult.setResult(userInfo);  
  14.       return executeResult;  
  15.   }  

设计实现:

 

1.添加国际化消息拦截器

我们的应用是基于struts2的,struts2默认提供了一个i18n拦截器,这里我们扩展了以下该拦截器的功能,将locale信息保存起来

 

  1. /** 
  2.  * 扩展struts2默认的i18n拦截器,添加设置local到LocaleContextHolder中的功能 
  3.  * @author WangXuzheng 
  4.  * @see com.opensymphony.xwork2.interceptor.I18nInterceptor 
  5.  * @see org.springframework.context.i18n.LocaleContextHolder 
  6.  */  
  7. public class I18nResolverInterceptor extends I18nInterceptor {  
  8.     private static final long serialVersionUID = 5888969294461266478L;  
  9.     @Override  
  10.     protected void saveLocale(ActionInvocation invocation, Locale locale) {  
  11.         super.saveLocale(invocation, locale);  
  12.         LocaleContextHolder.setLocale(locale);  
  13.     }  
  14. }  

2.在struts.xml中替换默认的i18n拦截器

 

 

  1. <interceptor name="i18n" class="com.haier.openplatform.i18n.interceptor.I18nResolverInterceptor"/>  

3.设计业务层国际化资源解析器接口

 

 

  1. /** 
  2.  * 国际化资源处理器 
  3.  * @author WangXuzheng 
  4.  * 
  5.  */  
  6. public interface I18nResolver {  
  7.     /** 
  8.      * 设置要进行资源处理的目标类 
  9.      * @param clazz 
  10.      */  
  11.     @SuppressWarnings("rawtypes")  
  12.     public void setClass(Class clazz);  
  13.     /** 
  14.      * 解析国际化资源文件,如果找不到该code,返回默认的消息 
  15.      * @param code i18n资源的key值 
  16.      * @return 如果找到返回具体的消息值,如果不存在返回默认消息 
  17.      * @see java.text.MessageFormat 
  18.      */  
  19.     String getMessage(String code);  
  20.       
  21.     /** 
  22.      * 解析国际化资源文件,如果找不到该code,返回默认的消息 
  23.      * @param code i18n资源的key值 
  24.      * @return 如果找到返回具体的消息值,如果不存在返回默认消息 
  25.      * @see java.text.MessageFormat 
  26.      */  
  27.     String getMessage(String code,String arg);  
  28.     /** 
  29.      * 解析国际化资源文件,如果找不到该code,返回默认的消息 
  30.      * @param code i18n资源的key值 
  31.      * @param args 资源中的变量值 
  32.      * @param defaultMessage 默认消息 
  33.      * @return 如果找到返回具体的消息值,如果不存在返回默认消息 
  34.      * @see java.text.MessageFormat 
  35.      */  
  36.     String getMessage(String code, Object[] args, String defaultMessage);  
  37.     /** 
  38.      * 解析国际化资源文件查找指定code对应的消息,如果不存在,抛出异常 
  39.      * @param code 
  40.      * @param args 
  41.      * @return 
  42.      * @throws MessageNotFoundException 
  43.      * @see java.text.MessageFormat 
  44.      * @throws MessageNotFoundException 
  45.      */  
  46.     String getMessage(String code, Object[] args);  
  47. }  

默认的实现类-这里我们的资源配置文件放在和待处理的类同文件下同名的.properties文件中

 

例如:java类

 

com.haier.openplatform.showcase.security.service.impl.UserServiceImpl

 对应的资源文件为

com/haier/openplatform/showcase/security/service/impl/UserServiceImpl_zh_CN.properties

com/haier/openplatform/showcase/security/service/impl/UserServiceImpl_en_US.properties

 

  1. /** 
  2.  * 默认的资源文件解析器,该类读取<code>org.springframework.context.i18n.LocaleContextHolder</code>中保存的Local信息解析资源文件 
  3.  * @author WangXuzheng 
  4.  * @see org.springframework.context.i18n.LocaleContextHolder 
  5.  */  
  6. public class DefaultI18nResolver extends MessageSourceSupport implements I18nResolver {  
  7.     private static final ConcurrentMap<String, ResourceBundle> BUNDLE_MAP = new ConcurrentHashMap<String, ResourceBundle>();  
  8.     private static final List<String> DEFAULT_RESOURCE_BUNDLES = new CopyOnWriteArrayList<String>();  
  9.     private static final Log LOG = LogFactory.getLog(DefaultI18nResolver.class);  
  10.     @SuppressWarnings("rawtypes")  
  11.     protected Class clazz;  
  12.     /** 
  13.      * 添加全局资源配置信息 
  14.      * 
  15.      * @param resourceBundleName the name of the bundle to add. 
  16.      */  
  17.     public static void addDefaultResourceBundle(String resourceBundleName) {  
  18.         //make sure this doesn't get added more than once  
  19.         synchronized (DEFAULT_RESOURCE_BUNDLES) {  
  20.             DEFAULT_RESOURCE_BUNDLES.remove(resourceBundleName);  
  21.             DEFAULT_RESOURCE_BUNDLES.add(0, resourceBundleName);  
  22.         }  
  23.   
  24.         if (LOG.isDebugEnabled()) {  
  25.             LOG.debug("Added default resource bundle '" + resourceBundleName + "' to default resource bundles = "  
  26.                     + DEFAULT_RESOURCE_BUNDLES);  
  27.         }  
  28.     }  
  29.   
  30.     /** 
  31.      * Creates a key to used for lookup/storing in the bundle misses cache. 
  32.      * 
  33.      * @param aBundleName the name of the bundle (usually it's FQN classname). 
  34.      * @param locale      the locale. 
  35.      * @return the key to use for lookup/storing in the bundle misses cache. 
  36.      */  
  37.     private String createMissesKey(String aBundleName, Locale locale) {  
  38.         return aBundleName + "_" + locale.toString();  
  39.     }  
  40.   
  41.     /** 
  42.      * 从全局资源文件中读取文案信息 
  43.      * 
  44.      * @param aTextName 文案 key 
  45.      * @param locale    the locale the message should be for 
  46.      * @return  
  47.      */  
  48.     private String findDefaultText(String aTextName, Locale locale) {  
  49.         List<String> localList = DEFAULT_RESOURCE_BUNDLES;  
  50.         for (String bundleName : localList) {  
  51.             ResourceBundle bundle = findResourceBundle(bundleName, locale);  
  52.             if (bundle != null) {  
  53.                 try {  
  54.                     return bundle.getString(aTextName);  
  55.                 } catch (MissingResourceException e) {  
  56.                     // ignore and try others  
  57.                 }  
  58.             }  
  59.         }  
  60.         return null;  
  61.     }  
  62.   
  63.     /** 
  64.      * 根据资源名称和locale信息查找资源信息 
  65.      * @param aBundleName the name of the bundle (usually it's FQN classname). 
  66.      * @param locale      the locale. 
  67.      * @return the bundle, <tt>null</tt> if not found. 
  68.      */  
  69.     protected ResourceBundle findResourceBundle(String aBundleName, Locale locale) {  
  70.         String key = createMissesKey(aBundleName, locale);  
  71.         ResourceBundle bundle = BUNDLE_MAP.get(key);  
  72.         if (bundle == null) {  
  73.             bundle = ResourceBundle.getBundle(aBundleName, locale, Thread.currentThread().getContextClassLoader());  
  74.             BUNDLE_MAP.put(key, bundle);  
  75.         }  
  76.         return bundle;  
  77.     }  
  78.   
  79.     private Locale getLocale() {  
  80.         return LocaleContextHolder.getLocale();  
  81.     }  
  82.   
  83.     @Override  
  84.     public String getMessage(String code) {  
  85.         return getMessage(code, new Object[] {});  
  86.     }  
  87.   
  88.     /** 
  89.      * 获取资源消息对应的值,先从指定的bundleName的资源中获取文案,如果找不到,从globalResources中读取 
  90.      * @param bundleName 
  91.      * @param locale 
  92.      * @param key 
  93.      * @param args 
  94.      * @return 
  95.      * @see #findResourceBundle 
  96.      */  
  97.     private String getMessage(String bundleName, Locale locale, String key, Object[] args) {  
  98.         ResourceBundle bundle = findResourceBundle(bundleName, locale);  
  99.         if (bundle == null) {  
  100.             return null;  
  101.         }  
  102.   
  103.         String orginalMessage = null;  
  104.         try {  
  105.             orginalMessage = bundle.getString(key);  
  106.         } catch (MissingResourceException e) {  
  107.             // read text from global resources  
  108.             orginalMessage = findDefaultText(bundleName, locale);  
  109.         }  
  110.         return this.formatMessage(orginalMessage, args, locale);  
  111.     }  
  112.   
  113.     @Override  
  114.     public String getMessage(String code, Object[] args) {  
  115.         return getMessage(resolveBunFile(), getLocale(), code, args);  
  116.     }  
  117.   
  118.     @Override  
  119.     public String getMessage(String code, Object[] args, String defaultMessage) {  
  120.         return StringUtils.defaultIfBlank(getMessage(code, args), defaultMessage);  
  121.     }  
  122.   
  123.     @Override  
  124.     public String getMessage(String code, String arg) {  
  125.         String[] args = new String[] { arg };  
  126.         return getMessage(code, args);  
  127.     }  
  128.   
  129.     protected String resolveBunFile() {  
  130.         String pack = this.clazz.getName();  
  131.         return pack.replaceAll("[.]""/");  
  132.     }  
  133.   
  134.     @SuppressWarnings("rawtypes")  
  135.     public void setClass(Class clazz) {  
  136.         this.clazz = clazz;  
  137.     }  
  138. }  

加一个静态工厂类来获取解析器

 

 

  1. /** 
  2.  * 资源解析器工厂类 
  3.  * @author WangXuzheng 
  4.  * 
  5.  */  
  6. public final class I18nResolverFactory {  
  7.     @SuppressWarnings("rawtypes")  
  8.     private static final ConcurrentMap<Class, I18nResolver> I18N_RESOVER_MAP = new ConcurrentHashMap<Class, I18nResolver>();  
  9.     private I18nResolverFactory(){  
  10.     }  
  11.       
  12.     @SuppressWarnings("rawtypes")  
  13.     public static I18nResolver getDefaultI18nResolver(Class clazz){  
  14.         I18nResolver resolver = I18N_RESOVER_MAP.get(clazz);  
  15.         if(resolver == null){  
  16.             resolver = new DefaultI18nResolver();  
  17.             resolver.setClass(clazz);  
  18.             I18N_RESOVER_MAP.put(clazz, resolver);  
  19.         }  
  20.         return resolver;  
  21.     }  
  22. }  

4.调用实现-非常类似log4j的调用方式

  1. public class UserServiceImpl implements UserService {  
  2.     private static final I18nResolver I18N_RESOLVER = I18nResolverFactory.getDefaultI18nResolver(UserServiceImpl.class);  
  3.     private UserDAO userDAO;  
  4.     private RoleDAO roleDAO;  
  5.   
  6. @Override  
  7.     public ExecuteResult<User> login(String userName, String password) {  
  8.         ExecuteResult<User> executeResult = new ExecuteResult<User>();  
  9.         User userInfo = userDAO.getUserByName(userName);  
  10.         if(userInfo == null){  
  11.             executeResult.addErrorMessage( I18N_RESOLVER.getMessage("user.notexisted"));  
  12.             return executeResult;  
  13.         }  
  14.         if(!userInfo.getPassword().equals(password)){  
  15.             executeResult.addErrorMessage(I18N_RESOLVER.getMessage("user.wrongpassword"));  
  16.             return executeResult;  
  17.         }  
  18.         executeResult.setResult(userInfo);  
  19.         return executeResult;  
  20.     }  

更多信息请查看 java进阶网 http://www.javady.com/index.php/category/thread

分享到:
评论

相关推荐

    金鼎国际物流业务管理系统

    为了提高金鼎国际物流管理的现代化水平,实现金鼎国际物流程序自动化、信息资源化、传输网络化、管理透明化和办公科学化,我们愿真诚地配合金鼎国际物流有关人员,一起开发《金鼎国际物流业务管理系统》。...

    某国际大酒店计算机网络系统设计方案.doc

    充分体现全网数 据共享、资源共享,充分满足领导层、管理层、业务层及不同业务部门的需求。 安全性: 除了物理设备上的安全性以外,还包括数据通信安全,网络的运行安全。网络安全重 在管理,严格的管理是保证网络...

    服务器虚拟化技术方案(1).doc

    四就是信息化平台应具有较强数据I/O处理能力,同时 系统在设计时必须考虑在大规模并发,长期运行条件下的系统可靠性,满足竹溪县民 政局信息化7×24小时的服务要求,保证各机构单位数据交换与资源共享的需要。...

    管理信息系统课程总结.doc

    4、开发决策支持系统,为企业决策层提供图形化、报表化的市场分析数据, 能够对未来的公司业务发展、市场发展、客户需求作出预测。5、信息化最直接的作用就 是全面降低企业运作成本,提高公司整体运作效率,大幅拓展...

    网通交换培训教材

    3.4.3 功能实体呼叫/业务逻辑处理模型 361 3.5 物理平面 362 3.5.1 概述 362 3.5.2 业务交换点SSP(Service Switching Point) 362 3.5.3业务管理点SMP(Service Management Point ) 362 3.5.4 网络接入点NAP...

    煤矿综合自动化系统方案设计.doc

    系统建成后,使各自动化子系统数据在异构条件下可进行有效集成和有机整合,实现相 关联业务数据的综合分析,集控中心人员或相关专业部门人员通过相应的权限对安全和 生产的主要环节设备实时监测和进行必要的控制,...

    中药材电子商务系统的设计(1).doc

    因此,开发中药材电子商务系统,实现中药材信息、中药材市场及交易过程 的电子化和信息化,对促进中药材市场的发展和中药商品国际化都具有重大意义。 1中药材电子商务系统的战略规划 经济全球化、贸易自由化和信息...

    Spring.3.x企业应用开发实战(完整版).part2

    5.5.3 容器级的国际化信息资源 5.6 容器事件 5.6.1 Spring事件类结构 5.6.2 解构Spring事件体系的具体实现 5.6.3 一个实例 5.7 小结 第6章 Spring AOP基础 6.1 AOP概述 6.1.1 AOP到底是什么 6.1.2 AOP术语 6.1.3 AOP...

    Spring3.x企业应用开发实战(完整版) part1

    5.5.3 容器级的国际化信息资源 5.6 容器事件 5.6.1 Spring事件类结构 5.6.2 解构Spring事件体系的具体实现 5.6.3 一个实例 5.7 小结 第6章 Spring AOP基础 6.1 AOP概述 6.1.1 AOP到底是什么 6.1.2 AOP术语 6.1.3 AOP...

    主机服务器运维管理制度.doc

    ——GB/T 22240-2008 信息安全技术 信息系统安全等级保护定级指南 三、总则 围绕公司打造经营型、服务型、一体化、现代化为总体目标,保障信息化建设,提 高运维能力,保证运维管理系统安全稳定的运行,明确岗位职责...

    GSM网络与GPRS

    4.4.2 事务处理能力应用子系统TCAP 4.5 PLMN的NSS功能结构 4.5.1 PLMN/RTC间的互联 4.5.2 MAP协议的一般介绍 4.6 小结 第5章 漫游、安全和呼叫管理 5.1 引入编码技术 5.1.1 IMSI国际移动用户身份 5.1.2 TMSI临时移动...

    经典JAVA.EE企业应用实战.基于WEBLOGIC_JBOSS的JSF_EJB3_JPA整合开发.pdf

    3.2.1 加载国际化资源文件 132 3.2.2 使用国际化消息 134 3.2.3 动态数据国际化 137 3.2.4 让用户选择语言 142 3.3 使用转换器完成类型转换 143 3.3.1 转换器概述、用途 144 3.3.2 JSF内建转换器 144 3.3.3 使用转换...

    TD-SCDMA基本原理和关键技术

    TD-SCDMA(Time Division Synchronous Code Division Multiple Access,时分同步码分多址)是由中国无线通信标准化组织(CWTS)制定,并被ITU(International Telecommunications Union,国际电信联盟)接纳的三大...

    环境应急系统建设调研报告.doc

    环境应急系统建设调研报告 湖南省环境保护厅: 根据湖南省...主要建设以下四个层次:"测得准"的智能多元化环境感知、"传 得快"的高速网络传输、"搞得清"的智慧信息处理、"管得好"的智能管理服务。建设监测 中心、监控

    J2EE中文版指南 CHM格式 带全文检索

    不受保护的EJB层资源 231 五.应用程序客户端层安全 231 确定应用程序客户端的回调处理机制 232 六.EIS(Enterprise Information System)层安全 232 配置契约 232 容器管理的契约 232 组件管理的契约 233 配置资源...

    智能调度平台系统技术要求.pdf

    2.7系统应采用多层B/S应用结构体系,表示层、业务层、数据 访问层要分开。 2.8系统应支持组件化开发,为第三方应用系统提供标准化数据 接口。 2.9 系统须具有分布式事务功能。 2.10系统须支持负载均衡及双机热备。 ...

    数据库课程设计—旅行社管理信息系统(1).doc

    由于旅游线路的增加和参团人员的增多和复杂性,旧的管理系统的处理能力和 管理方法很难满足现代化企业管理的需求,旧系统已成为实现企业战略目标的主要 障碍.但是公司的内部管理系统还不完善,还在进行以人工统计和...

    《3GPP长期演进(LTE)技术原理与系统设计》Part1

    1.2.2 国际宽带移动通信研究和标准化工作 3 1.2.3 我国宽带移动通信研究工作 5 1.3 3GPP简介 5 1.3.1 3GPP的组织结构 6 1.3.2 3GPP的工作方法 7 1.3.3 3GPP技术规范的版本划分 8 1.4 LTE研究和标准化工作进程 12 ...

Global site tag (gtag.js) - Google Analytics