GWT Dynamic Locale

2019-02-11 04:22发布

I want to set gwt-locale taking user chosen locale with the help of Spring LocaleContextHolder.

public static final String getCurrentLocale() {
    return LocaleContextHolder.getLocale().getLanguage();
}

I actually have login interface in Spring MVC and inner Dashboard in gwtp. The same locale user chooses in outer interface before login has to be passed to gwt as well.

Unfortunately, I don't see any gwt inbuilt Locale setters.

My X.gwt.xml with default locale as kh is :

<inherits name="com.google.gwt.uibinder.UiBinder" />
<inherits name="com.google.gwt.inject.Inject" />
<inherits name="com.gwtplatform.mvp.Mvp" />
<inherits name="gwtquery.plugins.droppable.Droppable"/>

<source path="client" />
<source path="shared" />

<define-configuration-property name="gin.ginjector" is-multi-valued="false"/>
<set-configuration-property name="gin.ginjector" value="com.prayagupd.client.mvp.XGInjector"/>
<set-configuration-property name="UiBinder.useSafeHtmlTemplates" value="true" /> 

<extend-property name="locale" values="kh" />
<extend-property name="locale" values="en" />
<set-property name="locale" value="kh"/>
<set-property-fallback name="locale" value="kh"/>

<entry-point class="com.prayagupd.client.XEntryPoint"/>

My XEntryPoint.java reads as :

public class XEntryPoint implements EntryPoint {

    private final IUserServiceAsync rpc = GWT.create(IUserService.class);

    @Override
    public void onModuleLoad() {
            //
        rpc.getLocale(new AsyncCallback<String>() {

            @Override
            public void onSuccess(String locale) {
                GWT.log("Locale From Spring : " + locale);
                GWT.log("Locale From GWT : " + LocaleInfo.getCurrentLocale().getLocaleName());
                            //here i want to set locale to gwt
                            //something like GWTLocale.setLocale(locale);
            }

            @Override
            public void onFailure(Throwable caught) {
                GWT.log(caught.getMessage());
            }
        });
            DelayedBindRegistry.bind(ginjector);
            ginjector.getPlaceManager().revealCurrentPlace();
    }
}

home.jsp for gwt-loading

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

<%@tag import="java.util.Calendar"%>
<%@ tag body-content="scriptless"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="spr" tagdir="/WEB-INF/tags"%>
<%@ attribute name="isgwt" required="true" type="java.lang.Boolean"%>


<!-- <!DOCTYPE html> -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>

<link rel="shortcut icon" type="image/png" href="/images/favicon.png" />
<script type="text/javascript" src="js/reload.captcha.js"></script>
<script type="text/javascript" src="js/date.picker.js"></script>
<link rel="stylesheet" href="/styles/innerstyle.css" type="text/css" />

<c:if test="${not isgwt}">
    <link rel="stylesheet" href="/styles/mainstyler.css" type="text/css" />
    <script type="text/javascript" src="js/modernizer.custom.js"></script>

    <script type="text/javascript" src="js/jquery.js"></script>
    <script type="text/javascript" src="js/jquery-ui-custom.min.js"></script>
    <script src="js/jquery.thumbnailScroller.js"></script>
</c:if>
<c:if test="${isgwt}">
<meta name="gwt:property" content="locale=${locale}">
<script type="text/javascript" language="javascript" src="upd/upd.nocache.js"></script>
</c:if>

<script type="text/javascript">
    $(window).load(function() {
        $('#slider').nivoSlider();
    });
</script>

<title><c:out value="${locale}"></c:out><spring:message code="page.header" /></title>
</head>
<body>
    <c:choose>
                <c:when test="${empty username}">
                    <div class="header_con">
                        <div class="header_in">
                            <spr:header />
                            <spr:login />
                            <div class="clear"></div>
                        </div>

                        <div class="main_con">
                            <jsp:doBody />
                            <spr:footer />
                        </div>
                        <div class="clear"></div>
                    </div>
                </c:when>
                <c:otherwise>
                    <div id="mainHolder">
                        <div id="wrapper">
                            <spr:headerInner />

                            <iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1'
                                style="position: absolute; width: 0; height: 0; border: 0"></iframe>
                            <div>

                                <div id="gwt_holder">
                                    <c:if test="${isgwt}">
                                        <div id="loader" class="loader">
                                        </div>
                                    </c:if>
                                    <div id="gwt"></div>
                                </div>
                            </div>
                        </div>
                    </div>
                </c:otherwise>
    </c:choose>
</body>
</html>

Adding ?locale=en or ?locale=kh to gwt url works perfectly, but want to tell GWT only once that I want this locale programmatically and want it to work always with that locale onwards.

When I look at the *.html source code, I can see the injected the <meta> tag with proper locale passed from SpringController.

enter image description here

References

GWT dynamic internationalization, Colin Alworth

How i change the locale language of the application

3条回答
我想做一个坏孩纸
2楼-- · 2019-02-11 05:08

Use a dynamic host page where you inject the proper <meta name="gwt:property" content="locale=XXX">.

Remember the GWT bootstrap sequence: once your onModuleLoad has been called, the choice of the permutation (which includes the locale) has already been made. You have to alter the bootstrap sequence so it chooses the proper permutation for the user. ?locale=XXX does this (because the locale property has a <property-provider> that reads the locale query-string parameter, among other things), as well as the <meta> above.

See also https://code.google.com/p/google-web-toolkit-incubator/wiki/ServerSideLocaleSelection for some idea (BEWARE: deprecated project!)

Finally, there are a few issues with your *.gwt.xml, starting with kh not being a valid locale.

The workflow for internationalizing your app is as follows:

  1. list your locales:

    <extend-property name="locale" value="en" />
    <extend-property name="locale" value="fr" />
    
  2. remove the default locale by setting the locale property to the full list of supported locales:

    <set-property name="locale" value="en,fr" />
    
  3. set the fallback locale:

    <set-property-fallback name="locale" value="en" />
    

Optionally, you can select how the locale is determined using the properties locale.queryparam, locale.cookie, locale.usemeta, locale.useragent, and locale.searchorder (see the I18N.gwt.xml for their default and accepted values).

And finally, add code to select the locale (e.g. the dynamic <meta> above)

查看更多
三岁会撩人
3楼-- · 2019-02-11 05:08

The solution inspired by Thomas Broyer,

X.gwt.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.3.0//EN" "http://google-web-toolkit.googlecode.com/svn/tags/2.3.0/distro-source/core/src/gwt-module.dtd">
<module rename-to="x">
    <inherits name="com.google.gwt.user.User"/>
    <inherits name="com.google.gwt.i18n.I18N" />
    <inherits name="com.google.gwt.http.HTTP" />
    <inherits name="com.google.gwt.json.JSON"/>

    <inherits name="com.google.gwt.uibinder.UiBinder" />
    <inherits name="com.google.gwt.inject.Inject" />
    <inherits name="com.gwtplatform.mvp.Mvp" />
    <inherits name="gwtquery.plugins.droppable.Droppable"/>

    <source path="client" />
    <source path="shared" />

    <define-configuration-property name="gin.ginjector" is-multi-valued="false"/>
    <set-configuration-property name="gin.ginjector" value="com.prayagupd.client.mvp.XGInjector"/>
    <set-configuration-property name="UiBinder.useSafeHtmlTemplates" value="true" /> 

    <extend-property name="locale" values="kh" />
    <extend-property name="locale" values="en" />
    <set-property-fallback name="locale" value="kh"/>

    <entry-point class="com.prayagupd.client.XEntryPoint"/>

</module>

And , home.jsp

<c:if test="${isgwt}">
<meta name="gwt:property" content="locale=${locale}">
<script type="text/javascript" language="javascript" src="upd/upd.nocache.js"></script>
</c:if>

locale being passed from Spring Controller

{
    //...
    modelMap.put("locale", locale);
    return "home";
}
查看更多
爱情/是我丢掉的垃圾
4楼-- · 2019-02-11 05:19

Thomas Broyer's answer is correct, except one thing. You don't mandatory need to use "dynamic host page", meta tag can be defined dynamically on the client side:

<script type="text/javascript">
    $.ajax("rest/service/default-locale").done(function(data) {
        if (data) {           
            var metaLocale = $("<meta name='gwt:property' content='locale=" + data + "'>");
            $("head").append(metaLocale);
        }
        var jsLink = $("<script src='myapp.nocache.js'>");
        $("head").append(jsLink);
    });
</script>

This way any additional modifications can be done on the client side before GWT app starts.

查看更多
登录 后发表回答