论坛首页 Java版

JSF的国际化怎么这么烂?

浏览 1253 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
最后更新时间:2008-02-21 关键字: jsf
JSF的国际化设计的真烂,简直就是对ResourceBundle的简单包装,为了在页面显示资源文件的内容,还得再每个页面指定<f:loadBundle basename="Application" var="msg"/>之类的标签,如果刚开始资源文件名称没命名好,或者是想挪个位置,那不是得满世界的改jsp文件?
用过jsf的兄弟,都来说说你们是怎么解决这个问题的?
   
最后更新时间:2008-02-21
Using Facelets might be a good solution, every page inherits a template page where you define the common stuff such as page layout,message bundle,etc. But you can not use jsp page any more,and you have to convert all the jsp page to .xhtml.

For example,1) Normal page: "createMedia.xhtml"

<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<ui:composition xmlns="http://www.w3.org/1999/xhtml"

xmlns:ui="http://java.sun.com/jsf/facelets"

xmlns:h="http://java.sun.com/jsf/html"

xmlns:f="http://java.sun.com/jsf/core"

xmlns:t="http://myfaces.apache.org/tomahawk"

template="../incl/basicTemplate.xhtml">

 

<!-- Create Media -->

<!-- content header-->

<ui:define name="contentHeader">

<h:outputText value="#{msg.create_media}"/>

</ui:define>

 

<!-- content body -->

<ui:define name="contentBody">

<h:form id="form">

<div id="media" class="section">

<div class="row">

<div class="light col input-label-required">

<h:outputText value="#{msg.name}"/>:

</div>

<div class="light col2 input-field">

<h:inputText id="mediaName" value="#{mediaBean.media.name}" size="50" maxlength="50" required="true"/>

</div>

</div>

<div class="row">

<div class="light col input-field">

<h:selectOneMenu id="format" value="#{mediaBean.media.format.id}" validator="#{mediaBean.validateSelection}" required="true">

<f:selectItems value="#{mediaBean.tapeFormatList}"/>

</h:selectOneMenu>

</div>

</div>

<div class="row">

<div class="dark col3 buttonField">

<h:commandButton value="#{msg.save}" action="#{mediaBean.createMedia}" styleClass="submit-button"/>

</div>

</div>

</div>

</h:form>

</ui:define>

</ui:composition>



2)Template page: "basicTemplate.xhtml"

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jstl/core">

<f:loadBundle basename="Messages" var="msg"/>
<f:view locale="#{localeSelector.locale}">


<head>
<title>
<ui:insert name="title"><h:outputText value="#msg.system_name}"></ui:insert>
</title>

<link rel="stylesheet" type="text/css" href="../../css/cmm-default.css" mce_href="../../css/cmm-default.css"></link>
<script language="JavaScript" src="../../js/cmm.js" mce_src="../../js/cmm.js"/>
<script language="JavaScript" src="../../js/timeDateFormatting.js" mce_src="../../js/timeDateFormatting.js"/>
</head>

<body> 
<div id="#{userBean.style}"> <!-- document -->
    <div id="header"></div>

    <div id="#{sessionScope.container}"> <!-- container -->
    <div>
        <ui:include src="menu.xhtml" mce_src="menu.xhtml"/>
    </div>
    <div id="contentHeader">
        <ui:insert name="contentHeader"/>
    </div>
    <div id="message">
        <ui:include src="message.xhtml" mce_src="message.xhtml"/>
    </div>
    <div id="contentBody">
        <ui:insert name="contentBody"/>
    </div>
    </div>
</div>
</body>
</f:view>
</html>

 

   
0 请登录后投票
最后更新时间:2008-02-22
这个方法也可以,但是还是需要指定哪个resource,我现在的做法是,按照一定的顺序查找所有的resources文件,结合managed bean 和自定义propertyResolver来处理。

 

/**
 * $Revision: 1.0 $
 * Created: 2008-2-21
 * $Date: 2008-2-21 $
 * 
 * Author: Keven Chen
 */
package demo;

import java.util.Locale;
import java.util.ResourceBundle;

/**
 * @author Keven Chen
 * @version $Revision 1.0 $
 *
 */
public class I18n {
	private String resources;
	private ResourceBundle bundle;

	public String getResources() {
		return resources;
	}

	public void setResources(String resources) {
		this.resources = resources;
	}
	
	private ResourceBundle getBundle(){
		if(bundle!=null){
			return bundle;
		} else {
			synchronized(this) {
				bundle = ResourceBundle.getBundle(resources);
			}
			return bundle;
		}
	}
	
	public String getText(String key){
		ResourceBundle bundle = getBundle();
		return bundle.getString(key);
	}
}

 

package demo;

import javax.faces.el.EvaluationException;
import javax.faces.el.PropertyNotFoundException;
import javax.faces.el.PropertyResolver;

public class DemoPropertyResolver extends PropertyResolver {

	private PropertyResolver originalResolver;
	
	public DemoPropertyResolver(PropertyResolver originalResolver){
		this.originalResolver = originalResolver;
	}
	@Override
	public Class getType(Object obj, Object obj1) throws EvaluationException,
			PropertyNotFoundException {
		if(obj instanceof I18n){
			return String.class;
		} else {
			return originalResolver.getType(obj, obj1);
		}
	}

	@Override
	public Class getType(Object obj, int i) throws EvaluationException, PropertyNotFoundException {
		if(obj instanceof I18n){
			return String.class;
		} else {
			return originalResolver.getType(obj, i);
		}
	}

	@Override
	public Object getValue(Object obj, Object param) throws EvaluationException,
			PropertyNotFoundException {
		if(obj instanceof I18n){
			return ((I18n) obj).getText(param.toString());
		} else {
			return originalResolver.getValue(obj, param);
		}
	}

	@Override
	public Object getValue(Object obj, int i) throws EvaluationException, PropertyNotFoundException {
		return originalResolver.getValue(obj, i);
	}

	@Override
	public boolean isReadOnly(Object obj, Object obj1) throws EvaluationException,
			PropertyNotFoundException {
		return originalResolver.isReadOnly(obj, obj1);
	}

	@Override
	public boolean isReadOnly(Object obj, int i) throws EvaluationException,
			PropertyNotFoundException {
		return originalResolver.isReadOnly(obj, i);
	}

	@Override
	public void setValue(Object obj, Object obj1, Object obj2) throws EvaluationException,
			PropertyNotFoundException {
		originalResolver.setValue(obj, obj1, obj2);
	}

	@Override
	public void setValue(Object obj, int i, Object obj1) throws EvaluationException,
			PropertyNotFoundException {
		originalResolver.setValue(obj, i, obj1);
	}

}

 

定义:

<managed-bean>
		<managed-bean-name>i18n</managed-bean-name>
		<managed-bean-class>demo.I18n</managed-bean-class>
		<managed-property>
			<property-name>resources</property-name>
			<value>Application</value>
		</managed-property>
		<managed-bean-scope>application</managed-bean-scope>
	</managed-bean>

 

使用的时候,只要:${i18n.key},key为properties文件的key值

 

 

   
0 请登录后投票
最后更新时间:2008-02-28
JSF1.2里对国际化问题已经有了改进
配置
<resource-bundle>
   <var>customMessages</var>
   <base-name>resources.CustomMessages</base-name>
</resource-bundle>

使用
<h:outputText value="#{customMessages.myText}" />
   
0 请登录后投票
最后更新时间:2008-03-27
http://www.operamasks.org/articles/magic-2/html_single
可以看看这篇文章,感觉里面的国际化做的还不错,有点意思。
   
0 请登录后投票
最后更新时间:2008-03-27
AOM做的国际化很有创意啊
   
0 请登录后投票
最后更新时间:2008-07-18
看来还是咱们的程序员最优秀,因为咱们总得面对客户的无理要求~
哈哈
   
0 请登录后投票
论坛首页 Java版

跳转论坛:
JavaEye推荐