I have a JSF 2.0 application that allows the user to change the language of the site, which should affect both texts and images.
Currently, the locale is set up in a bean session, and each page has a locale set from that bean session. It works great for texts. But I have image problems. We currently use these images:
<h:graphicImage name="flag.gif" library="img">
This results in the following HTML being returned to the user agent:
<img src="/AppRoot/faces/javax.faces.resource/flag.gif?ln=img" .... />
Suppose a user requests a page in English. The GET request for the image above is processed by ResourceHandler.handleResourceRequest (). It uses ViewHandler.calculateLocale () to determine the correct language prefix. I implemented my own ViewHandler using calculateLocale (), which retrieves the locale from a user session. As a result, it correctly creates an instance of the resource that points to "/resources/english/img/flag.gif" . The user then changes his language to French. When the page reloads, the same image URL is displayed and requested. This time, ViewHandler.calculateLocale () returns Locale.FRENCH in the ResourceHandler, which results in the creation of the resource using the path "/resources/french/img/flag.gif" .
Before streaming an image according to the ResourceHandler.handleResourceRequest () specification, it must do the following:
• Call Resource.userAgentNeedsUpdate (javax.faces.context.FacesContext). If this method returns false, HttpServletRequest.SC_NOT_MODIFIED should be passed to HttpServletResponse.setStatus (), then handleResourceRequest should return immediately.
It discovers that the resource has not been updated since the previous browser request - not taking into account that the previous request to this “logical” URL leads to a different “physical” resource on the server. And it returns HTTP 304, which results in the previous English image being displayed again to the user.
If the page is refreshed using Shift + F5, the French-language image will load correctly because the user agent sends an "If-Modified-Since" message.
It is always possible to add a local prefix manually using EL in the library name, for example:
<h:graphicImage library="#{userContext.locale}/img" name="flag.gif" />
But I still think the old approach should work cleaner.
I am wondering:
Why doesn't JSF create "src", which is the actual path to the image if we use the attributes "name" and "library"? JSF has all the information to build the full path on the initial page request, including the local UIViewRoot form (there is no need to implement my own ViewHandler). My guess is that this is due to the fact that, according to the specification, resources can also be placed in the JAR in the class path. However, the servlet URL could only be displayed to get the path to the cluster for which the direct URL could not be specified.
Why does the specification indicate that the "src" attribute of the generated image should contain a library, but does not say anything about the locale prefix (see Resource.getReqestPath ())? The src image is retrieved by Resource.getRequestPath (). If the prefix was included in the URL, French and English images will not be interpreted by the browser as one “changed” resource.
Any ideas are welcome!
image jsf jsf-2 localization
Irina marudina
source share