- 浏览: 1053703 次
文章分类
最新评论
-
cjh_android:
我想你是对的,至少对于现实是对的,不过对于技术岗位竞争越来越激 ...
程序员的思考--终于确定了自己的技术发展方向 -
dongbiying:
现在情况如何 。。
创业,不能兼职 -
jackyrong:
ie 9 下时,老显示关闭窗口提示,有办法去掉么,就是关闭掉那 ...
jquery右下角弹窗效果 -
lmaxjj:
加点班如果都称得上是累,只能说明还没体会到真正的生活。。
IT男的进化论 -
馨雨轩:
IT男要进化需要先穿越
IT男的进化论
用过struts2等mvc框架开发的同学都知道,使用struts2处理国际化的消息非常简单直观,但是mvc框架的定位是在展示层(jsp,action)等,在一个典型的3层结构中,处于最上层的位置,按照分层设计原则,下层组件是不可以调用上层组件的,这样就存在一个问题,我们在业务层中可能也会出现一些需要国际化处理的消息信息,这些信息如何设置呢?
在这篇文章中,我们将借鉴struts2的国际化处理机制,但是要比struts2简单的多,因为业务层需要国际化处理的消息毕竟是少数,废话不多说,直接上干货
先举个例子-业务层未国际化处理前的代码
- @Override
- public ExecuteResult<User> login(String userName, String password) {
- ExecuteResult<User> executeResult = new ExecuteResult<User>();
- User userInfo = userDAO.getUserByName(userName);
- if(userInfo == null){
- executeResult.addErrorMessage("不存在的用户名");
- return executeResult;
- }
- if(!userInfo.getPassword().equals(password)){
- executeResult.addErrorMessage("密码错误");
- return executeResult;
- }
- executeResult.setResult(userInfo);
- return executeResult;
- }
设计实现:
1.添加国际化消息拦截器
我们的应用是基于struts2的,struts2默认提供了一个i18n拦截器,这里我们扩展了以下该拦截器的功能,将locale信息保存起来
- /**
- * 扩展struts2默认的i18n拦截器,添加设置local到LocaleContextHolder中的功能
- * @author WangXuzheng
- * @see com.opensymphony.xwork2.interceptor.I18nInterceptor
- * @see org.springframework.context.i18n.LocaleContextHolder
- */
- public class I18nResolverInterceptor extends I18nInterceptor {
- private static final long serialVersionUID = 5888969294461266478L;
- @Override
- protected void saveLocale(ActionInvocation invocation, Locale locale) {
- super.saveLocale(invocation, locale);
- LocaleContextHolder.setLocale(locale);
- }
- }
2.在struts.xml中替换默认的i18n拦截器
- <interceptor name="i18n" class="com.haier.openplatform.i18n.interceptor.I18nResolverInterceptor"/>
3.设计业务层国际化资源解析器接口
- /**
- * 国际化资源处理器
- * @author WangXuzheng
- *
- */
- public interface I18nResolver {
- /**
- * 设置要进行资源处理的目标类
- * @param clazz
- */
- @SuppressWarnings("rawtypes")
- public void setClass(Class clazz);
- /**
- * 解析国际化资源文件,如果找不到该code,返回默认的消息
- * @param code i18n资源的key值
- * @return 如果找到返回具体的消息值,如果不存在返回默认消息
- * @see java.text.MessageFormat
- */
- String getMessage(String code);
- /**
- * 解析国际化资源文件,如果找不到该code,返回默认的消息
- * @param code i18n资源的key值
- * @return 如果找到返回具体的消息值,如果不存在返回默认消息
- * @see java.text.MessageFormat
- */
- String getMessage(String code,String arg);
- /**
- * 解析国际化资源文件,如果找不到该code,返回默认的消息
- * @param code i18n资源的key值
- * @param args 资源中的变量值
- * @param defaultMessage 默认消息
- * @return 如果找到返回具体的消息值,如果不存在返回默认消息
- * @see java.text.MessageFormat
- */
- String getMessage(String code, Object[] args, String defaultMessage);
- /**
- * 解析国际化资源文件查找指定code对应的消息,如果不存在,抛出异常
- * @param code
- * @param args
- * @return
- * @throws MessageNotFoundException
- * @see java.text.MessageFormat
- * @throws MessageNotFoundException
- */
- String getMessage(String code, Object[] args);
- }
默认的实现类-这里我们的资源配置文件放在和待处理的类同文件下同名的.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
- /**
- * 默认的资源文件解析器,该类读取<code>org.springframework.context.i18n.LocaleContextHolder</code>中保存的Local信息解析资源文件
- * @author WangXuzheng
- * @see org.springframework.context.i18n.LocaleContextHolder
- */
- public class DefaultI18nResolver extends MessageSourceSupport implements I18nResolver {
- private static final ConcurrentMap<String, ResourceBundle> BUNDLE_MAP = new ConcurrentHashMap<String, ResourceBundle>();
- private static final List<String> DEFAULT_RESOURCE_BUNDLES = new CopyOnWriteArrayList<String>();
- private static final Log LOG = LogFactory.getLog(DefaultI18nResolver.class);
- @SuppressWarnings("rawtypes")
- protected Class clazz;
- /**
- * 添加全局资源配置信息
- *
- * @param resourceBundleName the name of the bundle to add.
- */
- public static void addDefaultResourceBundle(String resourceBundleName) {
- //make sure this doesn't get added more than once
- synchronized (DEFAULT_RESOURCE_BUNDLES) {
- DEFAULT_RESOURCE_BUNDLES.remove(resourceBundleName);
- DEFAULT_RESOURCE_BUNDLES.add(0, resourceBundleName);
- }
- if (LOG.isDebugEnabled()) {
- LOG.debug("Added default resource bundle '" + resourceBundleName + "' to default resource bundles = "
- + DEFAULT_RESOURCE_BUNDLES);
- }
- }
- /**
- * Creates a key to used for lookup/storing in the bundle misses cache.
- *
- * @param aBundleName the name of the bundle (usually it's FQN classname).
- * @param locale the locale.
- * @return the key to use for lookup/storing in the bundle misses cache.
- */
- private String createMissesKey(String aBundleName, Locale locale) {
- return aBundleName + "_" + locale.toString();
- }
- /**
- * 从全局资源文件中读取文案信息
- *
- * @param aTextName 文案 key
- * @param locale the locale the message should be for
- * @return
- */
- private String findDefaultText(String aTextName, Locale locale) {
- List<String> localList = DEFAULT_RESOURCE_BUNDLES;
- for (String bundleName : localList) {
- ResourceBundle bundle = findResourceBundle(bundleName, locale);
- if (bundle != null) {
- try {
- return bundle.getString(aTextName);
- } catch (MissingResourceException e) {
- // ignore and try others
- }
- }
- }
- return null;
- }
- /**
- * 根据资源名称和locale信息查找资源信息
- * @param aBundleName the name of the bundle (usually it's FQN classname).
- * @param locale the locale.
- * @return the bundle, <tt>null</tt> if not found.
- */
- protected ResourceBundle findResourceBundle(String aBundleName, Locale locale) {
- String key = createMissesKey(aBundleName, locale);
- ResourceBundle bundle = BUNDLE_MAP.get(key);
- if (bundle == null) {
- bundle = ResourceBundle.getBundle(aBundleName, locale, Thread.currentThread().getContextClassLoader());
- BUNDLE_MAP.put(key, bundle);
- }
- return bundle;
- }
- private Locale getLocale() {
- return LocaleContextHolder.getLocale();
- }
- @Override
- public String getMessage(String code) {
- return getMessage(code, new Object[] {});
- }
- /**
- * 获取资源消息对应的值,先从指定的bundleName的资源中获取文案,如果找不到,从globalResources中读取
- * @param bundleName
- * @param locale
- * @param key
- * @param args
- * @return
- * @see #findResourceBundle
- */
- private String getMessage(String bundleName, Locale locale, String key, Object[] args) {
- ResourceBundle bundle = findResourceBundle(bundleName, locale);
- if (bundle == null) {
- return null;
- }
- String orginalMessage = null;
- try {
- orginalMessage = bundle.getString(key);
- } catch (MissingResourceException e) {
- // read text from global resources
- orginalMessage = findDefaultText(bundleName, locale);
- }
- return this.formatMessage(orginalMessage, args, locale);
- }
- @Override
- public String getMessage(String code, Object[] args) {
- return getMessage(resolveBunFile(), getLocale(), code, args);
- }
- @Override
- public String getMessage(String code, Object[] args, String defaultMessage) {
- return StringUtils.defaultIfBlank(getMessage(code, args), defaultMessage);
- }
- @Override
- public String getMessage(String code, String arg) {
- String[] args = new String[] { arg };
- return getMessage(code, args);
- }
- protected String resolveBunFile() {
- String pack = this.clazz.getName();
- return pack.replaceAll("[.]", "/");
- }
- @SuppressWarnings("rawtypes")
- public void setClass(Class clazz) {
- this.clazz = clazz;
- }
- }
加一个静态工厂类来获取解析器
- /**
- * 资源解析器工厂类
- * @author WangXuzheng
- *
- */
- public final class I18nResolverFactory {
- @SuppressWarnings("rawtypes")
- private static final ConcurrentMap<Class, I18nResolver> I18N_RESOVER_MAP = new ConcurrentHashMap<Class, I18nResolver>();
- private I18nResolverFactory(){
- }
- @SuppressWarnings("rawtypes")
- public static I18nResolver getDefaultI18nResolver(Class clazz){
- I18nResolver resolver = I18N_RESOVER_MAP.get(clazz);
- if(resolver == null){
- resolver = new DefaultI18nResolver();
- resolver.setClass(clazz);
- I18N_RESOVER_MAP.put(clazz, resolver);
- }
- return resolver;
- }
- }
4.调用实现-非常类似log4j的调用方式
- public class UserServiceImpl implements UserService {
- private static final I18nResolver I18N_RESOLVER = I18nResolverFactory.getDefaultI18nResolver(UserServiceImpl.class);
- private UserDAO userDAO;
- private RoleDAO roleDAO;
- @Override
- public ExecuteResult<User> login(String userName, String password) {
- ExecuteResult<User> executeResult = new ExecuteResult<User>();
- User userInfo = userDAO.getUserByName(userName);
- if(userInfo == null){
- executeResult.addErrorMessage( I18N_RESOLVER.getMessage("user.notexisted"));
- return executeResult;
- }
- if(!userInfo.getPassword().equals(password)){
- executeResult.addErrorMessage(I18N_RESOLVER.getMessage("user.wrongpassword"));
- return executeResult;
- }
- executeResult.setResult(userInfo);
- return executeResult;
- }
更多信息请查看 java进阶网 http://www.javady.com/index.php/category/thread
发表评论
-
网络地址转换(NAT,Network Address Translation)
2012-04-23 22:34 1565网络地址转换(NAT,Ne ... -
hibernate get()和load()
2012-04-23 22:32 1105Hibernate中有两个极为相似的方法get()与 ... -
23种设计模式(9):访问者模式
2012-04-23 22:31 1119定义:封装某些作用于某种数据结构中各元素的操作,它可以在 ... -
Java与Flex学习笔记(5)----Flex与Java通信之HttpService方式
2012-04-22 15:25 985Flex用RemoteObject方式与Java ... -
wp7 webbrowser+html5 打造本地应用程序(一)
2012-04-22 15:25 1546今天我终于实现了用webbrowser打开本地的一个ht ... -
技术文章是怎样炼成的?
2012-04-19 00:04 953这个是我看到过的非常棒的一篇文章,和大家分享一下 ...
相关推荐
总结来说,Struts的国际化处理涉及资源文件的创建、配置文件的设置、以及在Action和视图层如何正确引用这些资源。熟练掌握这一特性,能使你的应用更好地服务于全球用户,提升用户体验。通过学习和实践本资料包中的...
总结,这个Struts2国际化例子源码展示了如何在Java web应用中实现多语言支持,通过配置Struts2框架、编写Action类、创建资源文件以及在JSP页面中使用标签,实现了对不同语言环境的适应。这个例子对于理解和实践...
在Struts2中,资源配置文件和国际化(i18n)是两个非常重要的概念,它们对于创建多语言支持和提供用户友好的界面至关重要。 资源配置文件通常以.properties为扩展名,它们存储了应用中的静态文本,如错误消息、提示...
3. 分离业务逻辑:尽量避免在视图层(如JSP、HTML)中包含硬编码的字符串,确保所有需本地化的文本都在资源文件中。 4. 测试本地化:在多种语言环境下进行充分的测试,确保功能的完整性和正确性。 通过合理使用...
在这个“Struts+Hibernate+Spring(加入了struts完整的自动异常处理和国际化)源码”中,我们将深入探讨这三个框架的集成以及自动异常处理和国际化这两个关键特性。 首先,Struts作为MVC(模型-视图-控制器)框架,...
5. 国际化配置:国际化的实现通常涉及到资源文件(如`messages.properties`)的创建,这些文件包含了不同语言环境下的文本信息。在Spring MVC中,可以通过`LocaleResolver`和`MessageSource`接口来处理用户请求的...
2. **配置Struts 2**:在`struts.xml`配置文件中,我们需要添加特定的拦截器(interceptor)来处理国际化。`i18nInterceptor`是专门用于处理I18N的拦截器,它会自动从请求中获取用户的locale信息,并加载相应的资源...
- **Struts2配置**:配置Action支持国际化,关联对应的资源文件。 - **视图展示**:在JSP页面中使用EL表达式或Struts2标签动态显示对应语言的文本。 5. **表单验证**: - **Struts2的验证框架**:通过XML或注解...
- **业务集中**:当前大部分企业的人力资源信息化建设集中在基础业务处理,如招聘管理、薪酬管理等。 - **辅助解析不足**:相较于业务处理,辅助决策支持(如绩效评估、培训效果分析)的功能较弱。 - **信息渠道...
企业国际化发展战略是企业在全球范围内寻求发展机会的战略决策,旨在通过跨出国界,利用不同国家的资源、市场和机会,以实现更高的增长、盈利和竞争优势。本篇内容将深入探讨企业国际化经营的动机、战略环境分析以及...
- 设置国际化资源文件,并在JSP中调用。 5. **企业级软件开发**: - 在大型项目中,Struts1能够提供良好的结构和可维护性,便于团队协作。 - 结合其他JavaEE组件,如EJB、JMS等,可以构建复杂的企业级系统。 - ...
对于国际化,我们可以在控制器中使用`ModelAndView`对象将消息ID添加到模型中,然后在视图层(如JSP或Thymeleaf)中通过`<spring:message>`标签来获取对应的本地化消息。 总的来说,"验证与国际化需要的jar包"主要...
为了提高金鼎国际物流管理的现代化水平,实现金鼎国际物流程序自动化、信息资源化、传输网络化、管理透明化和办公科学化,我们愿真诚地配合金鼎国际物流有关人员,一起开发《金鼎国际物流业务管理系统》。...
这些技术是泛在电力物联网架构和标准体系的核心,它们通过汇集各方面的资源,为电力系统的规划建设、生产运行、经营管理、综合服务、新业务新模式发展以及企业生态环境构建提供充足有效的信息和数据支持。...
【Uber外卖平台国际化架构演化之路】的演进过程揭示了技术如何适应业务发展的需求,以及在面临全球化挑战时如何优化架构。以下是对Uber Eats架构发展的重要知识点的详细阐述: 1. **业务概述与挑战** - Uber Eats...
【数据处理服务外包】是指企业将数据相关的业务委托给第三方专业机构进行处理,通常包括数据采集、清洗、分析、存储等环节。这种模式在全球信息化进程中日益重要,特别是在我国产业结构调整的大背景下,服务外包成为...
【标题】"该示例整合了springmvc、mybatis、redis、shiro、国际化、主题",这是一段关于一个全面集成的Web应用项目描述,它涵盖了多个关键技术和框架,旨在构建一个功能丰富的Web应用程序。下面我们将逐一解析这些...
此方案的核心目标是以“国内领先,国际先进”的标准,构建一个集约化、智能化的水利信息化平台,实现对水利资源的全方位监控和高效管理。 1. **设计理念和建设思路** - **“五个一”理念**:该平台的设计围绕“一...
在JSP页面中,可以通过`<fmt:message>`标签来获取资源文件中的国际化消息。这需要在Struts配置文件中指定资源文件的位置,以便在页面上正确显示多语言文本。 通过这个项目,开发者可以学习到如何在Struts环境中...
【银行国际业务部怎么样】银行国际业务部是一个银行的核心部门...总的来说,银行国际业务部是银行业务发展的重要支柱,要求员工具备专业素养、创新思维和服务意识,通过不断学习和适应变化,促进银行业务的国际化进程。