• 关于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值,并且在执行完成后会重定向到请求的页面,也就解决了,页面无法显示正常语言的问题了。

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

  • 相关阅读:
    第二次冲刺阶段第四天
    第二次冲刺阶段第三天
    第二次冲刺阶段第二天
    人月神话阅读笔记03
    第二次冲刺阶段第一天
    学习进度条(十二)
    课堂练习-找水王
    学习进度条(十一)
    学习进度表第十周
    构建之法阅读笔记06
  • 原文地址:https://www.cnblogs.com/tf-swufe/p/3148917.html
Copyright © 2020-2023  润新知