我必须使用 JSF2 实现基于域的 I18N。
例如,如果域是
www.bookstore.com --> it should go to english site
www.bookstore.com.cn --> it should go to chinese site
www.bookstore.co.jp --> it should go to japanese site
我们拥有所有经过适当翻译的属性文件。当我更改浏览器语言/区域设置时,我可以看到翻译后的内容。但我们实际上并不需要这种行为。我在过滤器中根据域设置语言环境,它似乎不起作用。这是我的代码,这段代码有什么问题,问题出在哪里?
AuthenticationFilter.java
public class AuthenticationFilter implements Filter {
private static Log log = LogFactory.getLog(AuthenticationFilter.class);
@Override
public void init(FilterConfig config) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
FacesContext facesContext = FacesUtil.getFacesContext(httpRequest, httpResponse);
facesContext.getExternalContext().setResponseCharacterEncoding("UTF-8");
Locale requestLocale = LocaleUtil.getLocaleFromDomain(httpRequest);
if(requestLocale == null){
requestLocale = LocaleUtil.getDefault();
}
facesContext.getViewRoot().setLocale(requestLocale);
chain.doFilter(httpRequest, httpResponse);
}
@Override
public void destroy() {
}
}
FacesUtil.java
public class FacesUtil {
public static FacesContext getFacesContext(HttpServletRequest request, HttpServletResponse response) {
FacesContext facesContext = FacesContext.getCurrentInstance();
if (facesContext == null) {
LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
Lifecycle lifecycle = lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
FacesContextFactory contextFactory = (FacesContextFactory) FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
facesContext = contextFactory.getFacesContext(request.getSession().getServletContext(), request, response, lifecycle);
UIViewRoot view = facesContext.getApplication().getViewHandler().createView(facesContext, "");
facesContext.setViewRoot(view);
FacesContextWrapper.setCurrentInstance(facesContext);
}
return facesContext;
}
// Wrap the protected FacesContext.setCurrentInstance() in a inner class.
private static abstract class FacesContextWrapper extends FacesContext {
protected static void setCurrentInstance(FacesContext facesContext) {
FacesContext.setCurrentInstance(facesContext);
}
}
}
LocaleUtil.java
public class LocaleUtil {
public static Locale getLocaleFromDomain(HttpServletRequest request){
Locale locale=Locale.getDefault();
String domain = request.getHeader("HOST");
if(domain.contains(".com.cn"))
{
locale = new Locale(Locale.SIMPLIFIED_CHINESE.getLanguage(), Locale.CHINA.getCountry());
}else if(domain.contains(".co.jp"))
{
locale = new Locale(Locale.JAPANESE.getLanguage(), Locale.JAPAN.getCountry());
}else if(domain.contains(".co.kr"))
{
locale = new Locale(Locale.KOREAN.getLanguage(), Locale.KOREA.getCountry());
}else if(domain.contains(".com.tw"))
{
locale = new Locale(Locale.CHINESE.getLanguage(), Locale.TAIWAN.getCountry());
}
return locale;
}
public static Locale getDefault() {
Locale defaultLocale = new Locale("en", "US");
return defaultLocale;
}
}
面孔-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">
<application>
<locale-config>
<default-locale>en</default-locale>
<supported-locale>en_US</supported-locale>
<supported-locale>zh</supported-locale>
<supported-locale>zh_CN</supported-locale>
<supported-locale>zh_TW</supported-locale>
<supported-locale>ja</supported-locale>
<supported-locale>ja_JP</supported-locale>
</locale-config>
<resource-bundle>
<base-name>com.bookstore.component.BookStoreTextHandler</base-name>
<var>msg</var>
</resource-bundle>
</application>
</faces-config>
BookStoreTextHandler.java
public class BookStoreTextHandler extends ResourceBundle {
protected static final String BUNDLE_NAME = "/var/app/conf/bookstore";
protected static final String BUNDLE_EXTENSION = "properties";
protected static final Control UTF8_CONTROL = new UTF8Control();
public BookStoreTextHandler() {
Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
setParent(ResourceBundle.getBundle(BUNDLE_NAME, locale, UTF8_CONTROL));
}
@Override
protected Object handleGetObject(String key) {
return parent.getObject(key);
}
@Override
public Enumeration<String> getKeys() {
return parent.getKeys();
}
protected static class UTF8Control extends Control {
@Override
public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
throws IllegalAccessException, InstantiationException, IOException {
String bundleName = toBundleName(baseName, locale);
String resourceName = toResourceName(bundleName, BUNDLE_EXTENSION);
ResourceBundle bundle = null;
InputStreamReader reader = null;
FileInputStream fis = null;
try {
File file = new File(resourceName);
if (file.isFile()) { // Also checks for existance
fis = new FileInputStream(file);
reader = new InputStreamReader(fis, Charset.forName("UTF-8"));
bundle = new PropertyResourceBundle(reader);
}
} finally {
IOUtils.closeQuietly(reader);
IOUtils.closeQuietly(fis);
}
return bundle;
}
}
}
我有bookstore.properties, bookstore_en.properties, bookstore_en_US.properties, bookstore_zh.properties, bookstore_zh_CN.properties, bookstore_zh_TW.properties, bookstore.properties_ja, bookstore_ja_JP.properties
/var/app/conf/ 位置的文件。
介绍页.xhtml
<ui:composition lang="en" xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:ui="http://java.sun.com/jsf/facelets">
<div class="frame">
<h1>#{msg['bookstore.intro.title']}</h1>
</div>
<div>
<p style="line-height: 1.6em; font-family: Verdana, Arial, sans-serif;">
<h:outputText value="#{msg['bookstore.intro.paragraph.1']}" escape="false"/>
</p>
<p style="line-height: 1.6em; font-family: Verdana, Arial, sans-serif;">
<h:outputText value="#{msg['bookstore.intro.paragraph.2']}" escape="false"/>
</p>
<p style="line-height: 1.6em; font-family: Verdana, Arial, sans-serif; font-weight: bold;">
<h:outputText value="#{msg['bookstore.intro.paragraph.3']}" escape="false"/>
</p>
</div>
</ui:composition>
当我从不同的域尝试[我已经在本地更改了我的主机文件]时,当我调试过滤器代码时,它会根据域提供正确的区域设置。但不知道为什么总是得到英文内容。但是如果我更改浏览器语言,我可以看到翻译后的内容。这段代码有什么问题?