idea资源包下创建资源包_资源包技巧和最佳实践

idea资源包下创建资源包

今天是资源捆绑日。 通常,这是Java中最著名的国际化机制(i18n)。 使用它应该很容易。 但是,弄污双手时会出现许多小问题。 如果您有相同的想法,则此文章适合您。

基本

java.util.ResourceBundle定义了用于访问Java中翻译的标准化方法。 它们包含特定于语言环境的资源。 资源束属于其成员具有相同基本名称的族,但是其名称还具有其他标识组件的组件
他们的语言环境。 族中的每个资源束都包含相同的项目,但是这些项目已针对该资源束所代表的语言环境进行了翻译。 这些是键/值对。 这些键唯一地标识捆绑软件中特定于语言环境的对象。

最基本的示例使用以下知识:
Messages.properties
Messages_de.properties Messages_en.properties

如果您需要在应用程序中查询包,则只需调用

ResourceBundle bundle = ResourceBundle.getBundle("Messages");

方法并查询返回的包:

bundle.getString("welcome.message");

如果您想在此处使用哪种语言环境,那是对的。 String构造函数隐式使用Locale.getDefault()解析语言。 那可能不是您想要的。 所以你应该ResourceBundle bundle =

ResourceBundle.getBundle("Messages", locale);

检索捆绑软件后,您将无法设置语言环境。 每个ResourceBundle都有一个定义的语言环境。

命名的东西
 
关于命名的一些想法。 用其内容命名捆绑属性。 您可以通过简单地将它们命名为“ Messages”和“ Errors”等来采用更通用的方式。但是,每个子系统或组件也可以具有捆绑软件。 无论您需要什么。 要维护内容,要输入大量条目并不容易。 因此,任何类型的上下文拆分都会使开发人员感到高兴。 捆绑软件属性文件等效于类。 相应地命名。 进一步,您应该找到一个用于命名密钥的通用系统。 根据为属性文件选择的拆分,还可能在密钥中引入某种子系统或组件名称空间。 页面前缀也是可能的。 明智地考虑一下,并加以解决。 您的目标是尽可能减少密钥重复。

封装
 
如您所见,您经常使用包的字符串表示形式。 这些实际上是文件名(或更好的类名),您可以通过一个简单的枚举来更好地封装所有内容:

public enum ResourceBundles {MESSAGES("Messages"),ERRORS("Errors");private String bundleName;  ResourceBundles(String bundleName) {this.bundleName = bundleName;}public String getBundleName() {return bundleName;}@Overridepublic String toString() {return bundleName;}
}

有了这个你就可以写

ResourceBundle bundle = ResourceBundle.getBundle(MESSAGES.getBundleName());

Java Server Faces和ResourceBundle
 
要在基于jsf的应用程序中使用资源包,您只需在faces-config.xml中定义它们,并使用xhtml文件中的快捷方式。

<resource-bundle>
<base-name>Messages</base-name>
<var>msgs</var>
<h:outputLabel value="#{msgs['welcome.general']}" />

JSF负责其余的工作。 那参数替换呢? 考虑如下的键值对:

welcome.name=Hi {0}! How are you?

您可以通过f:param标签传递参数:

<h:outputFormat value="#{msgs['welcome.name']}"><f:param value="Markus" /></h:outputFormat>

要更改语言,您必须为当前的FacesContext实例设置特定的语言环境。 最好通过值更改侦听器执行此操作:

public void countryLocaleCodeChanged(ValueChangeEvent e) {String newLocaleValue = e.getNewValue().toString();//loop country map to compare the locale codefor (Map.Entry<String, Object> entry : countries.entrySet()) {if (entry.getValue().toString().equals(newLocaleValue)) {FacesContext.getCurrentInstance().getViewRoot().setLocale((Locale) entry.getValue());}}}

EJB中的资源包
 
JSF显然很容易集成。 在EJB中使用这些捆绑包怎么办? 基本上是一样的。 您有相同的机制来使用和使用捆绑包。 您应该记住一件事。 您可能不想始终使用默认语言环境。 因此,您必须找到一种从UI向下传递语言环境的方法。 如果您正在考虑通过@Produces注释@Injecting MessageBundle,则必须考虑多次。 尤其是在使用@Stateless EJB时。 这些实例被合并,您必须将语言环境传递给需要了解当前语言环境的任何业务方法。 通常,您可以使用参数对象或某种类型的用户会话配置文件执行此操作。 不要将语言环境全部添加为方法签名。

来自数据库的资源包
 
在大多数情况下,我看到您需要从数据库中提取密钥。 鉴于ResourceBundle的内部工作原理(每个语言环境一个“类”),您最终不得不在自己的ResourceBundle实现中实现逻辑。 您在网络上找到的大多数示例都是通过重写handleGetObject(String key)方法来实现的。 我不喜欢这种方法,特别是因为我们有一个更好的方法来使用ResourceBundle.Control机制。 现在,您可以覆盖newBundle()方法并返回自己的ResourceBundle实现。 您所要做的就是将自己的Control设置为DatabaseResourceBundle的父级:

public DatabaseResourceBundle() {setParent(ResourceBundle.getBundle(BUNDLE_NAME,FacesContext.getCurrentInstance().getViewRoot().getLocale(), new DBControl()));}

DBControl返回MyResourceBundle,它是一个ListResourceBundle:

protected class DBControl extends Control {@Overridepublic ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload)throws IllegalAccessException, InstantiationException, IOException {return new MyResources(locale);}/*** A simple ListResourceBundle*/protected class MyResources extends ListResourceBundle {private Locale locale;/*** ResourceBundle constructor with locale** @param locale*/public MyResources(Locale locale) {this.locale = locale;}@Overrideprotected Object[][] getContents() {TypedQuery<ResourceEntity> query = _entityManager.createNamedQuery("ResourceEntity.findForLocale", ResourceEntity.class);query.setParameter("locale", locale);List<ResourceEntity> resources = query.getResultList();Object[][] all = new Object[resources.size()][2];int i = 0;for (Iterator<ResourceEntity> it = resources.iterator(); it.hasNext();) {ResourceEntity resource = it.next();all[i] = new Object[]{resource.getKey(), resource.getValue()};values.put(resource.getKey(), resource.getValue());i++;}return all;}}}

如您所见,这由一个entitymanager和一个简单的ResourceEntity作为后盾,该ResourceEntity具有构建不同捆绑软件所需的所有字段和NamedQueries。

@Id@GeneratedValue(strategy = GenerationType.AUTO)private Long id;@Column(name = "i18n_key")private String key;@Column(name = "i18n_value")private String value;@Column(name = "i18n_locale")private Locale locale;

通过将捆绑包放入私有Map <String,String>值= new HashMap <String,String>(); 在首次构建捆绑包之后,您还可以使用一种很好的方法来缓存结果。

这仍然不是最好的解决方案,因为ResourceBundles具有缓存的方式。 但我稍后可能会更详细地探讨这一点。 到现在为止,该包将被永久缓存(或至少直到下一次重新部署为止)。

改写为语言切换
 
最后要提到的是,您还可以在此处添加一些精美的插件。 如果您已经有了JSF语言切换魔术,则可以轻松地将ocpsoft的重写添加到您的应用程序中。 这是一种将网址中的语言编码的简单方法,例如http://yourhost.com/Bundle-Provider-Tricks/en/index.html 您要做的就是通过添加两个简单的依赖关系来向游戏添加重写:

<dependency><groupId>org.ocpsoft.rewrite</groupId><artifactId>rewrite-servlet</artifactId><version>1.1.0.Final</version></dependency><dependency><groupId>org.ocpsoft.rewrite</groupId><artifactId>rewrite-integration-faces</artifactId><version>1.1.0.Final</version></dependency>

重写需要您添加自己的ConfigurationProvider,这是保存重写规则的中心位置。 执行以下操作:

public class BundleTricksProvider extends HttpConfigurationProvider {@Overridepublic Configuration getConfiguration(ServletContext context) {return ConfigurationBuilder.begin()// Locale Switch.addRule(Join.path("/{locale}/{page}.html").to("/{page}.xhtml").where("page").matches(".*").where("locale").bindsTo(PhaseBinding.to(El.property("#{languageSwitch.localeCode}")).after(PhaseId.RESTORE_VIEW)));}@Overridepublic int priority() {return 10;}
}

接下来是将一个名为“ org.ocpsoft.rewrite.config.ConfigurationProvider”的文件添加到您的META-INF / services文件夹,并在其中放置您的ConfigurationProvider实现的标准名称。 最后要调整的是LanguageSwitch bean中的逻辑。 重写不能触发ValueChangeEvent(据我所知:)),因此您必须在调用setter时添加一些魔术来更改Locale。 就是这样..非常简单!

参考:我们的JCG合作伙伴 Markus Eisele在企业软件开发和Java博客上的资源捆绑技巧和最佳实践 。


翻译自: https://www.javacodegeeks.com/2012/09/resource-bundle-tricks-and-best.html

idea资源包下创建资源包

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/353446.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MATLAB字符串输出

print();%最基本的字符串输出error();%主要用于报错

将JINQ与JPA和H2一起使用

几天前&#xff0c;我读了Iu Ming-Yee关于JINQ的有趣采访 。 顾名思义&#xff0c;JINQ是一种尝试提供类似于LINQ for Java的尝试。 基本思想是缩小在关系数据模型上执行查询的面向对象代码之间的语义鸿沟。 关系数据库模型的查询应轻松集成到代码中&#xff0c;以使其感觉更自…

蓝桥杯 2011年第二届C语言初赛试题(1)

轮换 串“abcd”每个字符都向右移位&#xff0c;最右的移动到第一个字符的位置&#xff0c;就变为“dabc”。这称为对串进行位移1的轮换。同理&#xff0c;“abcd”变为&#xff1a;“cdab”则称为位移2的轮换。 下面的代码实现了对串s进行位移为n的轮换。请补全缺失的代码。…

MATLAB读写mat文件

1. 保存mat文件&#xff1a;save %将工作区间中所有的变量都储存为MATLAB.mat文件中save filename %将工作区间中所有的变量都储存为filename.mat文件中save filename x1 x2 x3 ⋯⋯ xn %将工作区间中变量名位 x1 x2 x3 ⋯⋯ xn的变量都储存在filen…

奇偶换行颜色变化

<!DOCTYPE html><html> <head> <meta name"viewport" content"widthdevice-width"> <title>js</title> <style type"text/css"> td{ border: 1px solid red; } /* * 方法一 * tr:nth-child(odd):hove…

楼天城 楼教主

楼天城 求助编辑百科名片 楼天城楼天城是杭州人&#xff0c;姚期智教授的得意门生&#xff0c;正是姚教授发现他的才能后把他引上了现在的研究方向&#xff0c;并大力举荐他参加国际学术会议和比赛。在网络上他被称为“楼教主”&#xff0c;清华同学则简称他“教主”。中文名&a…

MATLAB读写Excel数据

读&#xff1a;[num,txt] xlsread(FileName.xls,n,basic);%num保存的是数据矩阵&#xff0c;txt保存的是文本矩阵&#xff0c;n是标签数从1开始计数,basic是区间&#xff0c;如A1:B3写&#xff1a;xlswrite(filename.xls,num,n,range);%:文件名&#xff0c;变量名&#xff0c;…

很多文章是在下转载贴在此处,是为了自己以后遇到类似问题一时想不起来

有转载有原创,更多是为了记录一些解决方案,,毕竟好记性不如烂笔头.转载于:https://www.cnblogs.com/wuchenV/p/9209356.html

jpa 与非jpa 结合_EasyCriteria –使用JPA标准的简便方法

jpa 与非jpa 结合今天&#xff0c;我们将看到有关此工具的信息&#xff0c;该工具使使用JPA Criteria更加容易。 使用该库的应用程序将在JPA实现中更加简洁&#xff0c;易于使用和可移植。 在本文的结尾&#xff0c;您将找到要下载的源代码。 什么是标准&#xff1f; 当前是创…

在c++中qsort()排序函数的使用qsort函数应用大全

七种qsort排序方法 <本文中排序都是采用的从小到大排序> 一、对int类型数组排序 int num[100]; Sample: int cmp ( const void *a , const void *b ) { return *(int *)a - *(int *)b; } qsort(num,100,sizeof(num[0]),cmp); 二、对char类型数组排序&#xff08;同in…

Python排序算法之快速排序

转自&#xff1a;https://www.cnblogs.com/AlwinXu/p/5424905.html 快速排序&#xff08;quickSort&#xff09; 快排的思想&#xff1a;首先任意选取一个数据&#xff08;通常选用数组的第一个数&#xff09;作为关键数据&#xff0c;然后将所有比它小的数都放到它前面&#x…

Apache PDFBox 2

Apache PDFBox 2已于今年早些时候发布 &#xff0c; Apache PDFBox 2.0.1和Apache PDFBox 2.0.2已发布。 Apache PDFBox是开源的&#xff08; Apache许可证版本2 &#xff09;并且基于Java&#xff08;因此易于使用&#xff0c;包括Java &#xff0c; Groovy &#xff0c; Scal…

HDU题目分类啊!!!

分类一&#xff08;详细&#xff09;&#xff1a; 分类二&#xff1a; 基础题&#xff1a;1000、1001、1004、1005、1008、1012、1013、1014、1017、1019、1021、1028、1029、1032、1037、1040、1048、1056、1058、1061、1070、1076、1089、1090、1091、1092、1093、1094、1095…

关于DP与背包

听说过动态规划&#xff08;DP&#xff09;的同学应该都知道有背包问题的存在。 首先我们来了解一下动态规划 基本思想&#xff1a; 动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中&#xff0c; 可能会有很多可行解。没一个解都对应于一个值&#xff0c;我们希…

MATLAB图像中添加标记

指定坐标添加标记: text(x,y,str)手动指定位置添加标记: gtext(str)横纵坐标xlabel()%横ylabel()%纵tittle()%标题

QQ空间说说的表情添加的代码

QQ空间说说的表情添加的代码 [em]e100[/em] 微笑 [em]e101[/em] 撇嘴[em]e102[/em] 色[em]e103[/em] 发呆[em]e104[/em] 得意[em]e105[/em] 流泪[em]e106[/em] 害羞[em]e107[/em] 闭嘴[em]e108[/em] 睡[em]e109[/em] 大哭[em]e110[/em] 尴尬[em]e111[/…

使用Spring boot,Thymeleaf,AngularJS从零开始构建一个新的Web应用程序-第3部分

在之前的博客中&#xff0c;我们使用Thymeleaf&#xff0c;Bower和Bootstrap构建了登录页面&#xff0c;并将其部署到了Heroku。 在此博客中&#xff0c;我们将介绍用于前端的AngularJS和在后端的Spring Boot Web服务的一些功能。 我们将从“登录/注销”部分开始。 让我们开始…

Nginx配置安装

安装之前准备1、依赖 gcc openssl-devel pcre-devel zlib-devel 安装&#xff1a;yum install gcc openssl-devel pcre-devel zlib-devel -y 安装Nginx./configure make && make install 默认安装目录&#xff1a;/usr/local/nginx 配置Nginx为系统服务&#xff0c;以…

matlab自定义窗口名

fg1figure(numbertitle,off,name,标题名称,color,white);saveas(fg1,保存图形的名称);clruprop 清除用户自定义属性setuprop 设置用户自定义属性getuprop 获取用户自定义属性