- 浏览: 116161 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
czqjay:
news/index/{pageNum}/{author} { ...
来谈谈REST、RBAC下的URL权限控制 -
csumck:
这也有一个在线时序图工具 http://echoma.git ...
推荐一个不错的在线“画”时序图的软件(通过文字生成图片) -
cpop:
...
如何将自己的jar包Release到Maven中央仓库中 -
yangzai911:
如果 accept-language中有值,那么也是默认取第一 ...
Play framework 国际化 -
wangyong8861850:
[color=darkred][/color][size=x- ...
EWeb4J 1.9.1 新版本发布 基于Servlet/JDBC的轻量级web开发框架
很荣幸也很开心地公布,EWeb4J 支持国际化了。并且有着它独特的味道。首先我们来看看最终的效果。
PS:
这个map获取之后,每次更改 locale,而不需要重新获取map,因为 map.get("key") 已经被代理了
看到了么?还是使用之前版本的 Props 来获取键值。使用上来说没有任何需要重新学习的地方。当然,你可以看到有个设置国际化语言的代码段:
怎么样?跟Play有点像?wow, 不不不。Play是这么用的:Lang.set(""),它是设置一个字符串,而在这是设置一个标准的 java.util.Locale。
有人问,支持 web 访问(浏览器语言设置等等)自动识别本地语言来进行国际化支持么?
答案是: Yes !
看看这个HelloAction.
是吧,真的跟上个版本一样调用的还是Props接口。
好了,在代码层面上就到这儿了,我们看看配置。
1.首先,start.xml多了一个配置
PS:后面的 country 是可选的
2.其次,准备好你的 properties 文件,老规矩,在 start.xml:
注意,这里的file的所有命名不需要跟国际化有任何关系。
3.虽然上面的配置文件里不需要写什么国际化语言,但是在你的文件系统里,你至少得准备好两份文件:
PS:这种命名法跟 Java 的国际化标准是一致的。国家country可以不填写。
4.文件内容:
message_en.properties
message_zh_CN.properties
PS:你可以很放心的使用中文!!这些文件目录也可以随便放,不一定都放在ClassPath中,因为EWeb4J没有使用ResourceBundle来处理它们。
好了,大概就这么多。下面稍微再说说:
EWeb4J 框架会自动的识别加载到你的国际化文件,而不需要显式的在配置文件指明,只需要指定一个BaseName即可。说到BaseName,还要说说Java国际化的内容,这里不详细说明,大概了解下,国际化资源文件命名规范:(优先级从上到下递增)
baseName.properties//例如 message.properties
baseName_language.properties//例如 message_zh.properties
baseName_language_country.properties//例如 message_zh_CN.properties
更加详细的内容请查阅相关资料。
对于 EWeb4J 框架来说,只需要告诉它 baseName 即可。另外,这个 baseName.properties是否必须存在跟另外两个文件有关系,如果另外两个存在(一个或都存在),那这个 baseName.properties 就可以不存在,框架是不会自动生成的。否则,框架会自动生成。
最后发一下EWeb4J实现国际化的几个关键源码:
!!正是因为这个代理类 MapProxy 的存在,所以在使用 Props.getMap("Message") 的 get("welcome") 的时候才会去找到匹配的国际化资源信息。这个很重要!!
package test.i18n; public class TestI18N { @BeforeClass public static void prepare() throws Exception { String err = EWeb4JConfig.start("start.eweb.xml"); if (err != null){ System.out.println(">>>EWeb4J Start Error --> " + err); System.exit(-1); } } @Test public void testVarable() throws Exception{ Map map = Props.getMap("Message"); Lang.set(Locale.US); Assert.assertEquals("Welcome to eweb4j !", map.get("welcome")); Lang.set(Locale.SIMPLIFIED_CHINESE); Assert.assertEquals("欢迎使用 eweb4j 框架 !", map.get("welcome")); } }
PS:
Map map = Props.getMap("Message"); Lang.set(Locale.CHINESE); map.get("welcome"); Lang.set(Locale.EN); map.get("welcome");
这个map获取之后,每次更改 locale,而不需要重新获取map,因为 map.get("key") 已经被代理了
看到了么?还是使用之前版本的 Props 来获取键值。使用上来说没有任何需要重新学习的地方。当然,你可以看到有个设置国际化语言的代码段:
Lang.set(Locale.US); Lang.set(Locale.SIMPLIFIED_CHINESE);
怎么样?跟Play有点像?wow, 不不不。Play是这么用的:Lang.set(""),它是设置一个字符串,而在这是设置一个标准的 java.util.Locale。
有人问,支持 web 访问(浏览器语言设置等等)自动识别本地语言来进行国际化支持么?
答案是: Yes !
看看这个HelloAction.
package org.eweb4j.crud; import org.eweb4j.cache.Props; public class HelloAction { public String doWelcome(){ return Props.getMap("Message").get("welcome"); } }
是吧,真的跟上个版本一样调用的还是Props接口。
好了,在代码层面上就到这儿了,我们看看配置。
<locales> <locale language="en" country="US" /> <locale language="zh" country="CN" /> </locales>
PS:后面的 country 是可选的
<properties> <file id="Message" path="message.properties" /> </properties>
注意,这里的file的所有命名不需要跟国际化有任何关系。
message_en_US.properties//或者message_en.properties message_zh_CN.properties//或者message_zh.properties
PS:这种命名法跟 Java 的国际化标准是一致的。国家country可以不填写。
#eweb4j last update 'framework' value #Sat May 05 02:00:40 CST 2012 framework=eweb4j welcome=Welcome to ${framework} !
message_zh_CN.properties
#eweb4j last update 'framework' value #Sat May 05 02:00:40 CST 2012 framework=eweb4j welcome=欢迎使用 ${framework} 框架 !
PS:你可以很放心的使用中文!!这些文件目录也可以随便放,不一定都放在ClassPath中,因为EWeb4J没有使用ResourceBundle来处理它们。
好了,大概就这么多。下面稍微再说说:
更加详细的内容请查阅相关资料。
对于 EWeb4J 框架来说,只需要告诉它 baseName 即可。另外,这个 baseName.properties是否必须存在跟另外两个文件有关系,如果另外两个存在(一个或都存在),那这个 baseName.properties 就可以不存在,框架是不会自动生成的。否则,框架会自动生成。
最后发一下EWeb4J实现国际化的几个关键源码:
//代理类,在Props.java内部 private static class MapProxy<K, V> implements Map<K,V>{ private String id; private Map<K,V> map(){ String _id = id+"_"+Lang.get().toString(); if (props.containsKey(_id)) return (Map<K, V>) props.get(_id); else{ _id = id + "_" + Lang.get().getLanguage(); if (props.containsKey(_id)) return (Map<K, V>) props.get(_id); } return (Map<K, V>) props.get(id); } public MapProxy(String id){ this.id = id; } public V get(Object key) { Map map = this.map(); return (V) (map == null ? null : map.get(key)); } //...... } //在获取缓存的时候,判断该ID是否拥有国际化资源文件,若有,使用代理 public static Map<String, String> getMap(String id) { if (i18nIds.contains(id)) return new MapProxy<String, String>(id); return props.get(id); } // 读取properties的全部信息 public static synchronized String readProperties(Prop f, boolean isCreate)throws IOException { if (f == null || f.getPath().length() == 0) return null; String id = f.getId(); String path = f.getPath(); ConfigBean cb = (ConfigBean) SingleBeanCache.get(ConfigBean.class); I18N i18n = cb.getLocales(); final String sufPro = ".properties"; if (i18n != null){ for (Locale l : i18n.getLocale()){ String suffix1 = "_"+l.getLanguage()+"_"+l.getCountry(); String tmpPath1 = path.replace(sufPro, suffix1 + sufPro); i18nIds.add(id); if (FileUtil.exists(ConfigConstant.CONFIG_BASE_PATH+ tmpPath1)){ Prop p = new Prop(); p.setGlobal("false"); p.setId(id + suffix1 ); p.setPath(tmpPath1); readProperties(p, false);//递归,把国际化文件内容加载仅缓存 isCreate = false;// 如果存在国际化文件,那么默认的文件允许不存在 continue; } String suffix2 = "_"+l.getLanguage() ; String tmpPath2 = path.replace(sufPro, suffix2 + sufPro); if (FileUtil.exists(ConfigConstant.CONFIG_BASE_PATH+ tmpPath2)){ Prop p = new Prop(); p.setGlobal("false"); p.setId( id + suffix2 ); p.setPath( tmpPath2 ); readProperties(p, false);//递归,把国际化文件内容加载仅缓存 isCreate = false;// 如果存在国际化文件,那么默认的文件允许不存在 continue; } } } //............ }
!!正是因为这个代理类 MapProxy 的存在,所以在使用 Props.getMap("Message") 的 get("welcome") 的时候才会去找到匹配的国际化资源信息。这个很重要!!
package org.eweb4j.i18n; import java.util.List; import java.util.Locale; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eweb4j.config.ConfigConstant; import org.eweb4j.config.Log; import org.eweb4j.config.LogFactory; import org.eweb4j.config.bean.I18N; import org.eweb4j.mvc.Context; import org.eweb4j.mvc.MVC; import org.eweb4j.mvc.MVCCons; /** * EWeb4j 国际化支持 * @author weiwei * */ public class Lang { private static Log log = LogFactory.getMVCLogger(Lang.class); private static ThreadLocal<Locale> current = new ThreadLocal<Locale>(); public static Locale get(){ Locale locale = current.get(); if (locale == null){ Context ctx = MVC.current.get(); if (ctx != null){ HttpServletRequest req = ctx.getRequest(); HttpServletResponse res = ctx.getResponse(); if (req != null){ resolve(req, res); }else{ setDefaultLocale(); } }else{ setDefaultLocale(); } locale = current.get(); } return locale; } private static void resolve(HttpServletRequest req, HttpServletResponse res) { Cookie[] cookies = req.getCookies(); if (cookies != null){ for (Cookie cookie : cookies){ if (MVCCons.COOKIE_KEY_LOCALE.equals(cookie.getName())){ String loc = cookie.getValue(); if (loc == null) continue; if (loc.indexOf("_") > 0){ String[] locs = loc.split("_"); if (set(new Locale(locs[0], locs[1]))){ return ; } } if (set(new Locale(loc))) return; } } } Locale locale = req.getLocale(); set(locale); res.addCookie(new Cookie(MVCCons.COOKIE_KEY_LOCALE, locale.toString())); } public static boolean set(Locale locale){ if (I18N.get().contains(locale)){ log.debug("Locale is set -> %s", locale.toString()); current.set(locale); return true; } log.warn("Locale %s is not defined in your %s > i18n", locale, ConfigConstant.START_FILE_NAME); return false; } public static void clear(){ current.remove(); } public static void change(Locale locale){ if (get() == null){ if (set(locale)) MVC.current.get().getResponse().addCookie(new Cookie(MVCCons.COOKIE_KEY_LOCALE, locale.toString())); }else{ if (!get().equals(locale)){ if (set(locale)) MVC.current.get().getResponse().addCookie(new Cookie(MVCCons.COOKIE_KEY_LOCALE, locale.toString())); } } } private static void setDefaultLocale() { List<org.eweb4j.config.bean.Locale> locales = I18N.get().getLocale(); if (locales == null || locales.isEmpty()){ set(Locale.getDefault()); } else{ set(new Locale(locales.get(0).getLanguage(), locales.get(0).getCountry())); } } }
发表评论
-
EWeb4J 1.9.1 新版本发布 基于Servlet/JDBC的轻量级web开发框架
2012-11-28 22:08 2813EWeb4J 是一个基于 Servlet/Jdbc 构建的轻量 ... -
EWeb4J-SolidBase 发布新版本
2012-07-08 12:41 2124SolidBase项目是采用 DWZ + EWeb4J 开发的 ... -
EWeb4J 框架迁移到 GitHub
2012-07-05 10:02 1885EWeb4J 框架: https://github.com/ ... -
发布一个EWeb4J-1.9的Demo
2012-07-04 16:38 26EWeb4J-1.9框架发布在即,在此之前,发布一个小Demo ... -
EWeb4J-1.9-文件上传下载和生成建表脚本
2012-06-09 12:11 2299毕业了。高兴一下,哈。 一直以来,eweb4j framew ... -
SolidBase 二次开发 GIS 截图
2012-05-07 16:12 1907有位大哥哥使用 EWeb4J 的项目 SolidBase 作为 ... -
Play framework 国际化
2012-05-03 20:04 4301Play的国际化操作还是非常简单的。大概分为四步: 1. ... -
eweb4j在线演示程序更新
2012-04-25 09:25 2092访问地址:SolidBase 增加菜单显示权限 ... -
EWeb4J-1.9-继续改善ActiveRecord支持【级联】操作
2012-04-17 20:58 1485老习惯:约定优于配置 ... -
EWeb4J-1.9-控制器更新
2012-04-13 16:56 1442主要增加以下更新: 验证器 声明式事务 7个默认Acti ... -
eweb4j-1.9-支持ActiveRecord模式
2012-04-06 20:46 1616@Entity @Table(name="t_ ... -
(不断更新)EWeb4J-1.9-SNAPSHOT最近进程
2012-03-28 23:33 1813经过奋战,终于有个稳定点的SNAPSHOT版本咯。 较之上个 ... -
eweb4j演示项目-SolidBase增加对菜单显隐的权限控制
2012-03-28 14:41 1897昨晚捣鼓到两点多才弄好,今天整理了下,大概把菜单权限控制做好了 ... -
(下篇)单例POJO实现CRUD+分页+搜索Demo
2012-03-23 23:14 2本篇程序特点: POJO式的控制器,无需继承、无需实 ... -
体验快速开发2:单例POJO实现CRUD+分页+搜索Demo
2012-03-23 22:54 29程序特点: POJO式的控制器,无需继承、无需实现接 ... -
体验快速开发:只有一个控制类实现的CRUD+分页+搜索Demo
2012-03-22 22:17 182╮(╯▽╰)╭,本来不想谈什么快速开发的,但是最近老是有人拿什 ... -
如何将自己的jar包Release到Maven中央仓库中
2012-03-20 17:17 4432PS:真正要发布到Maven中央库中是首先需要到https:/ ... -
EWeb4J-1.8.6 发布,同时带来一个演示项目
2012-03-08 17:44 2986距离上次1.7的发布已经过去5个月了。首先值得高兴的是EW ... -
eweb4j加进到Maven中央仓库啦,先发个快照版
2012-02-25 23:54 1691挺开心的。 先是注册好了 eweb4j.org。 然后是sv ... -
eweb restful需要考虑的,谨记。
2012-02-20 19:25 1154框架是否遵守一条HTTP消息并非仅仅包含一个URI的原则?也 ...
相关推荐
eweb4j是一个Java开发框架,它专注于提供高效、轻量级且易于使用的Web应用程序解决方案。这个框架的设计理念是简化开发流程,提高开发效率,同时保持代码的清晰性和可维护性。下面我们将深入探讨eweb4j框架的核心...
为了适应多语言环境,`eweb4j`支持国际化和本地化功能。开发者可以创建资源文件,存储不同语言的文本,框架会根据用户设置自动加载对应的语言版本。 **日志管理** 良好的日志系统对于问题排查至关重要。`eweb4j`...
EWeb4J ? = EWeb4J 是一个基于 Servlet/Jdbc 构建的轻量级 Java Web 开发框架。它可以代替 SSH 来开发一个完整的 Web 应用程序。 它专注于 少侵入、少配置、松耦合、RESTful架构风格的 Web 应用程序开发。 EWeb4J ...
Rockwell 1756-Eweb模块
EWeb通常有详细的用户手册和在线社区支持。学习这个实例,你将发现如何利用这些资源解决遇到的问题,提升自己的技能。 总结,EWeb在线编辑器应用实例是一个全面的学习资料,涵盖了从基础编辑功能到高级特性的...
针对全球化需求,EWeb编辑器2.80版支持多语言页面制作,方便创建多语言网站,扩大受众范围。 8. **版本控制与备份**: 提供版本历史记录功能,用户可以随时回溯到之前的编辑状态,避免误操作导致的损失,同时也...
这款编辑器支持上传功能,极大地扩展了其在网页设计和内容管理中的应用范围。 首先,eWeb7.3.0商业版在线HTML编辑器的核心特性是它的易用性。用户无需具备深厚的HTML语言基础,只需通过直观的图形化界面,就能完成...
eWeb Editor的飞鱼修改版源码更是为开发者提供了进一步定制和优化的可能性,使得这款编辑器能够更好地适应不同项目的需求。 eWeb Editor的核心特性在于其对HTML、CSS以及JavaScript等Web语言的良好支持。用户可以...
4. **HTML源码编辑**:对于有经验的用户,eweb也提供了直接编辑HTML源码的功能,以便进行更精细的控制和自定义。 5. **表格与布局**:编辑器内建了表格创建和编辑工具,用户可以轻松创建复杂的表格结构,调整列宽和...
如果有错误,eweb编辑器通常会提供错误信息,帮助定位问题。 7. **版本控制**: - 在进行此类更改时,务必使用版本控制系统(如Git)来跟踪文件的变更,以便在出现问题时可以轻松回滚。 8. **安全考虑**: - ...
在线编辑HTML,使用户方便使用编码在线编辑HTML,使用户方便使用编码
7. **多语言支持**:作为“完整中文版”,eWeb Editor 3.8 除了中文界面外,还可能支持其他多种语言,适应全球用户的需求。 8. **兼容性和跨平台**:编辑器兼容各种主流浏览器,如Internet Explorer、Firefox、...
1756-EWEB
ASP常用的后台编辑器,带图片上传功能 调用方法如下例子: <textarea name="nr" ROWS="20" COLS="70">%=Server.HTMLEncode(rs("nr"))%></textarea> <iframe ID="eWebEditor1" src="../...</iframe>
EWeb4J支持多种数据库,并提供了强大的表单验证功能,使得开发者可以轻松创建复杂的数据驱动型Web应用。 #### 3. Spring Roo 1.2.1 **下载链接**: ...
【标题解析】:“[MMS_041397]Reading CLX_val using EWEB.rar”这个标题可能指的是一个关于使用EWEB工具读取AB PLC(Allen Bradley Programmable Logic Controller)中的CLX(可能是ControlLogix系列)寄存器或变量...
压缩包内的文件"eweb.e"可能是一个易语言工程文件,包含了整个项目的源代码和资源。"CCHTTP2.0.2.0zip.ec"可能是CCHTTP模块的更新版本,提供新的功能或修复了之前的bug。"精易模块[v8.1.5].ec"是易语言的精易模块,...
4. **语言支持**:从标签"language"可以看出,该控件提供了多语言支持,方便国内外用户使用。 5. **注意问题**:描述中提到上传功能目前不支持Struts2.0框架,这意味着在使用Struts2.0的项目中,可能需要寻找替代的...
在处理过程中,DreamEdit会去除那些Eweb不支持或者可能导致显示异常的复杂格式,同时保留基本的文本内容和简单样式,使得在Eweb中查看时,文本的可读性和整洁度得以保证。 此外,软件的“help”文件提供了详细的...
eWeb editor编辑器文件,说明,使用方法:将解压后的editor文件夹拷贝到项目根目录下,在需要的页面中加入以下内容: 办事内容:</font></td> ;style=s_blue" frameborder="0" width="99%" ...