Right now, the Gwt algorithm used for language detection, only considers the language parameter in the url, the locale meta-tag, and the javascript variable __gwt_Locale. With these options, the developer has to provide whether links to the user to select the adequate language, or server-side code able to read the Accept-Language header, which has to be called before the gwt application is loaded. Take a look to this post to know exactly how to do the server-side language detection.
However, it is possible to know the language the user is using asking the browser as is explained in this page.
The language reported by the browser is just the language used for the application (menus, messages, etc), and not the Accept-Language header, but it covers a hight percentage of cases. It works fine when an user selects the language at login time in linux, Mac, other un*x, and with the default user's language in windows.
So, simply adding the code below to your .gwt.xml file, your application will select the correct language for most user cases, and you don't need to add complex stuff to do the selection in server side.
I have sent a patch to gwt guys which I expect could be included soon in the official trunk.
<property-provider name="locale"> <![CDATA[ try { var locale; // Look for the locale as a url argument if (locale == null) { var args = location.search; var startLang = args.indexOf("locale="); if (startLang >= 0) { var language = args.substring(startLang); var begin = language.indexOf("=") + 1; var end = language.indexOf("&"); if (end == -1) { end = language.length; } locale = language.substring(begin, end); } } if (locale == null) { // Look for the locale on the web page locale = __gwt_getMetaProperty("locale") } if (locale == null) { // Look for an override computed by other means in the selection script locale = $wnd['__gwt_Locale']; } if (locale == null) { // Use the browser's locale locale = navigator.browserLanguage ? navigator.browserLanguage : navigator.language; if (locale != null) { locale = locale.replace(/-/g, '_'); } } if (locale == null) { return "default"; } while (!__gwt_isKnownPropertyValue("locale", locale)) { var lastIndex = locale.lastIndexOf("_"); if (lastIndex == -1) { locale = "default"; break; } else { locale = locale.substring(0,lastIndex); } } return locale; } catch(e){ alert("Unexpected exception in locale detection, using default: " + e); return "default"; } ]]> </property-provider>