From: JP PAWLAK\(Tiscali\) <jp....@ti...> - 2003-02-21 07:04:09
|
Envoy=E9 : jeudi 20 f=E9vrier 2003 22:50 =C0 : 'Trevor Cook' Objet : RE : [Springframework-developer] Explicit locales =20 I use a solution near of yours but with a more generalist approach. To keep the users locale, different possibilities exist: session, cookie, URL. But each solution can be handled knowing the request object. So I use a bean for implementing the effective strategy in the way of the general spirit of Spring. 1) Create a simple interface like this: public interface LocaleLocator { Locale getSessionLocale(HttpServletRequest request); void setSessionLocale(HttpServletRequest request, Locale sessionLocale); } 2) Create an implementation class which in your case handles with the cookies, but which can use the session or what method you like. 3) Overriding the ControllerServlet to use a LocaleLocator property with at least the setter, so the implementation class can be done in the servlet-configuration file. <bean name=3D"localeLocator" singleton=3D"true" class=3D"perso.jpp.fwk.web.LocaleLocatorImpl" /> =20 <bean name=3D"jstlHandler" singleton=3D"true" class=3D"perso.jpp.fwk.web.JstlHandlerImpl" > =20 <property name=3D"bundleName">achappro</property> </bean> =20 code added in declaration part: // Added by JPP /** The bean name allowing the user session locale to be retrieved */=20 public static final String LOCALE_LOCATOR =3D "localeLocator"; =20 /** The bean name allowing the jstl ressouece bundle to be set */=20 public static final String JSTL_HANDLER =3D "jstlHandler"; =20 /** LocaleLocator used by this servlet * If not provided, request.getLocale() will be used instead */ =20 private LocaleLocator localeLocator; // End added =20 =20 code added in ControllerServlet (or descendent) at end of initFrameworkServlet : initViewResolver(); =20 // Added by JPP try { localeLocator =3D (LocaleLocator) =20 getWebApplicationContext().getBean(LOCALE_LOCATOR);=20 logger.config("localeLocator found in servlet '" + getServletName()=20 + "' : " + localeLocator.getClass().getName()); } catch(Exception e) { localeLocator =3D null; // Not required as it should yet been null logger.config("No localeLocator found in servlet '" + getServletName() + "', request Locale will be used."); } // Jstl handling // Put only in a subclass ? But Jstl is ageneric use // The ApplicationContextAware doesn't provide an access to the servletContext // It's the reason of an initialisation here. Exists a best approach ? try { JstlHandler jstlHandler =3D (JstlHandler) =20 =20 getWebApplicationContext().getBean(JSTL_HANDLER);=20 jstlHandler.setServletCtx(this.getServletContext()); logger.config("jstlHandler found in servlet '" + getServletName()=20 + "' : " + jstlHandler.getClass().getName()); } catch(Exception e) { logger.config("No jstlHandler found in servlet '" + getServletName()); } =20 // End added =20 4) As you can see, I handle I a same way the definition of locale and bundle for JSTL. 5) The LocaleLocator can be donated by beanref property to objects which have to know the current locale having the request object. =20 I hope this will be a useful add-on in this discussion. I suggest to integrate a such behaviour in the original ControllerServlet as thes needs are very generally. =20 Regards, Jean-Pierre =20 -----Message d'origine----- De : spr...@li... [mailto:spr...@li...] De la part de Trevor Cook Envoy=E9 : jeudi 20 f=E9vrier 2003 21:38 =C0 : Spring Developers (E-mail) Objet : RE: [Springframework-developer] Explicit locales =20 It sounds like you're on the right track, and your approach should work for my stuff. I've already implemented some of this (code below) by overriding ControllerServlet and checking for a cookie in doService before passing control up. I store the locale in a persistent cookie so that no session is created for simple site browsing, and to remember chosen language for future visits. I'm sure my approach could be improved alot, but it's just a prototype (so I could get my html guy to start working). When you're implementing it, a few suggestions/ideas/requests. If this is put into the framework, you probably want to allow the developer to specify whether to make it cookie or session-based. If it is cookie-based, you'll probably also need to allow the developer to specify browser or persistent (including max age). Trevor D. Cook =20 public class LocaleServletController extends ControllerServlet { public static final String LOCALE_HANDLE =3D "locale"; protected void doService( HttpServletRequest request, HttpServletResponse response, boolean debugMode) throws ServletException, IOException { String locale =3D request.getParameter(LOCALE_HANDLE); if (locale !=3D null) { logger.info("Setting locale to: " + locale); setLocaleCookie(request, response, locale);=20 } else { getLocale(request); } super.doService(request, response, debugMode); } private void getLocale(HttpServletRequest request) { Cookie[] cookies =3D request.getCookies(); int cookiesSize =3D cookies.length; for (int i =3D 0; i < cookiesSize; i++) { if (LOCALE_HANDLE.equals(cookies[i].getName())) { String localeCookie =3D cookies[i].getValue(); setLocale(request, localeCookie); } } } private void setLocaleCookie( HttpServletRequest request, HttpServletResponse response, String localeString) { Locale locale =3D setLocale(request, localeString); Cookie localeCookie =3D new Cookie(LOCALE_HANDLE, localeString); if (locale.equals(request.getLocale())) { localeCookie.setMaxAge(-1); } else { localeCookie.setMaxAge(365 * 24 * 60 * 60); } response.addCookie(localeCookie); } private Locale setLocale( HttpServletRequest request, String localeString) { Locale locale =3D new Locale(localeString.substring(0, 2), localeString.substring(2)); request.setAttribute("locale", locale); return locale; } } =20 =20 -----Original Message----- From: j=FCrgen h=F6ller [werk3AT] [mailto:jue...@we...] Sent: February 20, 2003 3:21 PM To: Spring Developers (E-mail) Subject: Re: [Springframework-developer] Explicit locales Trevor, =20 I've noticed that issue too. We definitely need support for a manually set locale in the session, already for 1.0. I consider 1. the only viable option but I think of a very easy and generic way: Why not just define a Spring standard name for a session attribute that can contain a Locale instance? The ControllerServlet could first check the session for such an attribute and fall back to the request locale. =20 A custom application will probably not support changing the locale with every possible action but rather with a special one controller URL. That controller implementation could put a respective attribute into the session, with the given standard name, and update user preferences in the database or set a respective cookie if desired. Of course, the user's locale has to be retrieved for a new session - that could happen after login in a login controller, or in a custom filter that checks for a certain cookie. =20 So the minimal framework support needed seems to be the definition of a standard name for a session locale, and checking the session when determining a view in the ControllerServlet. Of course, custom applications can not only set that locale but also retrieve it in controllers that perform locale-specific actions. =20 I'm currently in the process of polishing Spring's web part (probably taking over responsibility for it, at least for 1.0), so I could add such locale support easily. Would the outlined approach be sufficient for you? If yes, I will add that support prompty, probably commiting the changes at the beginning of next week. =20 Regards, Juergen =20 =20 -----Urspr=FCngliche Nachricht----- Von: Trevor Cook [mailto:tc...@in...]=20 Gesendet: Donnerstag, 20. Februar 2003 03:55 An: Spring Developers (E-mail) Betreff: [Springframework-developer] Explicit locales I have a business requirement of handling multiple locales. Specifically, I live in Canada, and the application must be available in French and English. However, due to multiple users on a single computer, we cannot rely solely on the users locale settings. What we need to do is default to the users locale, but provide them with the ability to override these settings (probably by clicking an "English/French" link). Anyway, the framework question I have is "is there anyway to do this currently"? Looking at the controller servlet, it returns a view based on "request.getLocale()". This can't be changed, so I can't see any way to customize/change it. My ideas are: 1. Have an explicit object in the request attribute for the locale with a "hook" to define how the default is determined (request locale, cookie, session, etc.). The view (or any other locale "lookup") would be based on this attribute. 2. Wrap the request/response objects in the control servlet, and provide hooks for these wrappers (which could override the getLocale() method). 3. Have the view return a generic view, and have the view contain code/taglibs which do the locale stuff in it.=20 4. Any other ideas?=20 My "rating" of my own arguments is that 1 is the best since it abstracts the locale to the start of the servlet request as an initial parameter (which is how I consider it). 2 requires a lot of customization to support what appears to be something others might use (however, the ability to override other methods might be desirable). 3 is ugly code, and removes all the benefits of Rod's framework for seamlessly handling the locale issues. We probably can't make any of these changes for the 1.0 release (if we can great, but I'm trying to be realistic) but I was looking for some ideas and counter-arguments. I need to go ahead with this project (I'm actually waiting on this issue right now, but I think I've bought myself till Monday :) ) so I'll probably need to make my own modifications to a local copy of the code, but if my direction makes sense to everyone, I can probably polish/generalize my changes and roll it into the main stream in a future release. Trevor D. Cook=20 =20 --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.449 / Virus Database: 251 - Release Date: 1/27/03 =20 =20 --- Incoming mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.456 / Virus Database: 256 - Release Date: 2/18/03 --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.456 / Virus Database: 256 - Release Date: 2/18/03 |