3

I'm trying to create a localized JSF web application which allows user to select a language via dropdown. When language is selected, I simulate a redirect to the same page but with URL parameter:

window.location.replace(urlToMyApp + '?locale=DE');

Next, I read 'locale' parameter in application's web filter and write it in a cookie with the same name:

String localeValue = httpRequest.getParameter("locale");
Cookie cookie = new Cookie("locale", localeValue);
cookie.setMaxAge(-1);
cookie.setDomain(cookieDomain);
cookie.setPath(cookiePath);
httpResponse.addCookie(cookie);

Now when I try to read that cookie in request bean init method, cookie is not available. If I select another language via dropdown (EN for example), previously selected language (DE) is read in init method.

I assume that cookie written in filter is not available before next "request - response" cycle, can someone confirm that?

If that's true I'm asking for an idea to translate my application immediately after selecting another language.

Just one thing that I think I need to mention - language dropdown is not part of my application. It's part of some kind of framework for several applications to be included (like portal).

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
peterremec
  • 488
  • 1
  • 15
  • 46

1 Answers1

5

I assume that cookie written in filter is not available before next "request - response" cycle, can someone confirm that?

That's correct.

You've added the new cookie to the response, not to the request. So any attempt to read it from the same request won't work. The cookie will only be available in the request if the browser has actually sent it. But it can only do that if it has obtained the cookie data from a previous response.

If that's true I'm asking for an idea to translate my application immediately after selecting another language.

If the request scoped bean is managed by CDI @Named, then just inject it in the filter and set the locale over there.

@Inject
private Bean bean;

public void doFilter(...) {
    // ...

    bean.setLocale(locale);

    // ...
}

Else if it's not managed by CDI, but by the since JSF 2.3 deprecated @ManagedBean, then manually instantiate it and put it in request scope so that JSF will just reuse the same bean.

public void doFilter(...) {
    // ...

    Bean bean = new Bean();
    bean.init(); // If necessary.
    bean.setLocale(locale);
    request.setAttribute("bean", bean); // "bean" is managed bean name.

    // ...
}

See also:

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • thank you for your explanation. About your proposal - instantiating request bean in filter would most likely solve my problem. But the thing is that the same filter is used by numerous applications running in my "framework" so I guess I'd need to instantiate all request beans from all of my apps, right? – peterremec Feb 08 '21 at 20:15
  • Alternatively split it into another bean which you inturn then inject in "all request beans from all of your apps". – BalusC Feb 10 '21 at 16:44
  • Sounds like a good idea, thanks. Meanwhile I was thinking about saving locale value as a session attribute. Value should be available in the same request-response cycle, right? – peterremec Feb 10 '21 at 17:15
  • Just make that newly split bean `@SessionScoped` instead of `@RequestScoped`. – BalusC Feb 10 '21 at 17:21