关于JSF国际化问题

由于最近一个项目的MVC层框架用的是JSF,所以在摸索中遇到了不少的问题,其中有一项就是关于国际化的的问题。

小弟在网上找了很多的资料,其实无外乎内容就都那样,可不知是小弟人品太差还是由于确实技术上有问题,按照网上的配置老是会出现如下情况。

页面上有一个选择语言栏的下拉框,当小弟选择不同语言的时候,由于调用(action或者actionlistener)的方法没有返回值,页面会出现在当前页面刷新的状况,可是页面刷新之后,上面的输出依旧没有改变,是中文的还是中文,但是在浏览器重新打开一个窗口访问当前URL的时候,就会发现语言已经切换了,不知道大家明白我说的没有。简单说就是点击更换语言后页面有刷新动作,但实际在页面上看不出变化,一旦重新打开一个窗口(new window 不是 new session),就可以看到变化后的结果。

后来小弟发现,其实只要在点击语言选择栏后,为调用的方法增加返回值(也就是返回一个String),在配置文件中跳转回当前页面并加上<redirect/>标签,也就是说在你每次选择完语言后,页面会重定向到当前页面,一切就显示正常了。

但这里出现了一个问题,如果有十个甚至一百个页面,那岂不是要写上成百上千个导航配置,那样是很麻烦的。

因此,我想起了servert中的HttpServletResponse的重定向方法,那么我只需要在更改语言的方法中,每次更改完语言地区后利用HttpServletResponse重定向会当前的请求发起页面不就解决了吗,因此我写了如下代码。

首先,为了可扩展性,我定义了一个abstract的父类BaseBo,这个类主要就是用于在JSF框架中取得HttpServert的一些内置对象,以及sping的一个获取bean的方法。

import javax.faces.application.Application;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

public abstract class BaseBO {

    // Get FacesContext
    protected FacesContext getFacesContext() {
        return FacesContext.getCurrentInstance();
    }

    // Get Application
    protected Application getApplication() {
        return getFacesContext().getApplication();
    }

    // Get HttpServletRequest
    protected HttpServletRequest getRequest() {
        return (HttpServletRequest) getFacesContext().getExternalContext()
                .getRequest();
    }

    // Get HttpServletResponse
    protected HttpServletResponse getResponse() {
        return (HttpServletResponse) getFacesContext().getExternalContext()
                .getResponse();
    }

    // Get HttpSession
    protected HttpSession getSession() {
        ExternalContext extContext = FacesContext.getCurrentInstance()
                .getExternalContext();
        HttpSession session = (HttpSession) extContext.getSession(false);
        return session;
    }
    // Get Bean
    protected Object getBeanObject(String beanName) {
        ApplicationContext ctx = WebApplicationContextUtils
                .getWebApplicationContext(getSession().getServletContext());    
        return ctx.getBean(beanName);
    }
}

然后我有一个专门用于控制loacle的类和方法,并继承了BaseBo,如下代码(PS, locale属性已经通过spring容器默认注入了"cn")

import java.io.IOException;

import javax.faces.event.ValueChangeEvent;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LocaleBo extends BaseBO {

    private String locale;

    public String getLocale() {
        return locale;
    }

    public void setLocale(String locale) {
        this.locale = locale;
    }

    // Change locale setting.
    public void changeLocale(ValueChangeEvent e) throws IOException {
        HttpServletRequest request = this.getRequest();
        HttpServletResponse response = this.getResponse();
        if (locale.equals("cn")) {
            locale = "en";
        } else {
            locale = "cn";
        }
        String reqURL = request.getRequestURI();
        System.out.println(reqURL);
        response.sendRedirect(reqURL);
    }
}

页面选择语言的下拉代码如下(managed-bean配置以及properties文件的配置就不多讲了,不懂的可以问问谷大哥或者百大哥)

<f:view locale="#{localeSetting.locale}">
    <f:loadBundle basename="resources.messages" var="msgs" />
        <h:form>
            <h:selectOneMenu styleClass="toplink" immediate="true"
                onchange="this.form.submit();" value="#{localeSetting.locale}"
                valueChangeListener="#{localeSetting.changeLocale}">
                <f:selectItem itemValue="en" itemLabel="#{msgs.LBL_EN_LANGUAGE}" />
                <f:selectItem itemValue="cn" itemLabel="#{msgs.LBL_CN_LANGUAGE}" />
            </h:selectOneMenu>
        </h:form>
</f:view>

支持,当你每次选择下拉菜单的时候,都会调用changeLocale方法去改变locale值,并且在执行完成后会重定向到请求的页面,也就解决了,页面无法显示正常语言的问题了。

可能之前看文章不仔细才造成小弟不得不这样“瞎搞”,还望各位高手指出,但请勿喷我啊,小弟会流泪的,哈哈,感谢了。

原文地址:https://www.cnblogs.com/tf-swufe/p/3148917.html