#544: Localization & BeanValidation
Pavel Bucek
Dear experts, we are working on improving integration with BeanValidation [1], and seems like if we choose to address this issue, the change will be slightly bigger than I anticipated. In short, the issue is about providing Locale based on incoming request to the BV runtime, which can then choose it to provide localized error message. Since there is no way how to get a list of supported locales, we'd need to introduce a provider, which would register supported locales: public interface SupportedLocaleProvider {
List<Locale> getSupportedLocales();
}
If the application contains @Provider annotated subclass of this interface and there is a BV message to be produced, implementation would be required to do something like:
SupportedLocaleProvider supportedLocaleProvider = ...; javax.ws.rs.Request request = ...; List<Locale> locales = supportedLocaleProvider.getSupportedLocales(); javax.ws.rs.Variant.VariantListBuilder variantListBuilder = Variant.VariantListBuilder.newInstance(); List<Variant> vs = variantListBuilder.languages(locales.toArray(new Locale[]{})).build(); Variant v = request.selectVariant(vs); (+ null checks, etc). If selected variant exists, then "v.getLanguage()" would be used as a Locale passed to BV runtime.
Please let us know what do you think about proposed solution of linked issue. Also, the introduced interface might have more uses that just this (maybe too specific) case - any brainstorming ideas to what it could be used are welcomed. Thanks and regards, Pavel
|
|
Sergey Beryozkin
Hi Pavel Where would usually the code wishing to pass the Locale get the list of supported locales from, without even getting JAX-RS involved ? If there was some well-known mechanism then the JAX-RS runtime would just use it as opposed to having to deal with a new provider... Cheers, Sergey
On 22/05/17 17:46, Pavel Bucek wrote:
|
|
A JAX-RS application produces machine-readable information (XML, JSON, etc.), hence it does not support ANY human language by definition. BV provides machine-readable ConstraintViolations for this purpose; the message text plays no role in "real" REST, just like any message text of any Exception is of no interest to the end user. In a RESTful scenario, the translation of the BV exception is up to the front end designer, hence the CLIENT programmer (like MVC API, JSF, JavaFX) just as HE has to find nice and translated phrases for ANY OTHER exception already: Exceptions are INTERNAL and not to be forwarded 1:1 to the end user! So it is up to HIM to define the languages, while the text contained in a server's "error page" should stay in the same language always as it is NOT intended for the end user but for the programmer / administrator / devop! Hence how shall the author of a JAX-RS application ever decide which languages to support? JAX-RS does NOTHING with this information as you already said! In addition, what happens if the application programmer declares to define Chinese, but the BV implementation does not support Chinese? That won't work. I would rather say, this is solely a MVC feature and should not be defined by JAX-RS.
|
|
Bean Validation spec lead here, thanks a lot for considering this feature!
> Since there is no way how to get a list of supported locales Why is it that you need to get the list of locales? The Locale mechanism has fallback implemented which is used by Bean Validation. So e.g. say you have ValidationMessages.properties, ValidationMessages_en.properties and ValidationMessages_de.properties. If you request with "en" or "en_US", it'd take the second. If you request with "de", it'd take the last one. If you request with any other Locale, it'd take the first one. This all happens automatically. > hence the CLIENT programmer (like MVC API, JSF, JavaFX) just as HE has to find nice and translated phrases for ANY OTHER exception already I think there are good reasons for doing I18N on the server and on the client, it's not that one is always better than the other. E.g. doing it on the backend (i.e. JAX-RS) allows different clients to benefit from translations (say a JavaFX client as well as a web client using the same REST API). JSF btw. is integrating with Bean Validation already in the suggested way: it takes its current Locale and passes it to BV. I personally think JAX-RS could do it exactly in the same way: set up a Bean Validation message interpolator which takes the Locale from requests and passes this to calls of interpolate(). --Gunnar
|
|
Santiago Pericas-Geertsen
Hi Gunnar,
toggle quoted messageShow quoted text
Other than message interpolation, is there any other scenario where locale information is important in BV? What comes to mind is a string that contains a representation of a locale-specific date format, for example. Pavel and I were discussing locale support included but not limited to message interpolation. I think you’re right about the fallback for messages. — Santiago
|
|
If we want to support I18N on the JAX-RS server, it only would be straightforward to not only translation BV messages, but we also have to provide similar services to ALL providers, too. For example, why should it be correct that BV is supported, but custom exception providers are not, also custom MBWs (like for PDF) are not? I mean, content is content, and a service should be available to ALL sources of content, not just to BV.
From: jaxrs-spec@javaee.groups.io [mailto:jaxrs-spec@javaee.groups.io] On Behalf Of Gunnar Morling via Groups.Io
Sent: Mittwoch, 24. Mai 2017 17:54 To: jaxrs-spec@javaee.groups.io Subject: Re: [jaxrs] #544: Localization & BeanValidation
Bean Validation spec lead here, thanks a lot for considering this feature!
|
|
Pavel Bucek
We are still not exactly sure how / whether it should be put into place. JAX-RS implementation has to have list of supported locales, because there is a defined algorithm, which chooses effective locale for the response. Note that Accept-Language is a list of languages, not a single one. Thus we'd need to somehow get a list of supported languages and invoke algorithm which computes effective language/Locale for the response entity. If there would be BV API which could do that, it would be great (I mean - if there would be a way how to pass a list of possible locales and let BV runtime to do the rest). Introducing new interface like SupportedLocaleProvider is viable option, but when I try to get into a "user role", I would expect something more from that - maybe adding Language header to the response. That is certainly possible, but again problematic, since there is no guarantee that the response entity will respect that (and JAX-RS would need to provide a way how to obtain computed Language). Also, seems like one of the main motivations for doing this is to provide support for MVC - and if there is Provider priority, this could be handled on MVC side (including BV, if MVC chooses to use it).. Regards,
On 25/05/2017 08:56, Markus KARG wrote:
|
|
Sergey Beryozkin
Can those providers which need it, ex, BV exception mappers, depend on the existing injectable Configuration interface to ensure the locales or other info can be accessed in a portable way ?
Cheers, Sergey
|
|
> Note that Accept-Language is a list of languages, not a single one
Ah, that's a good point, I wasn't aware of that. My feeling is that JAX-RS should select the right Locale (however that would look like), so it can apply it across all sorts of providers/services it interacts with and then pass that one to Bean Validation. > one of the main motivations for doing this is to provide support for MVC I'm not so sure about that, I think JAX-RS itself would benefit from it, too. --Gunnar
|
|
Pavel Bucek
On 26/05/2017 10:14, Gunnar Morling via Groups.Io wrote:
> Note that Accept-Language is a list of languages, not a single one selecting a right locale might be problematic. Imagine you have two resource method, one serving orders and the other one items. Items can be returned in different set of languages than orders. Then, if we delegate this selection to JAX-RS, we need to support it per resource method? How would SupportedLanguageProvider do that? Also, it could be that this information is stored in a database and is even item specific. How would be that provider written then? I'm not saying it is not possible, it would bring additional complexity to something, which can be already handled (in application specific way) without providing any real benefit. The struggle here is with the SupportedLanguagesProvider - it feels like it should be used for something more than BV - I think it's fair to say that if localizaiton of BV error messages is the sole purpose of such provider, it shouldn't be introduced. And I can't think of any other sensible use right now. Regards, Pavel
|
|
Hey Pavel,
I would like to take the opportunity to describe what MVC did to support internationalization which relates to the issue we are discussing here. As MVC builds on top of JAX-RS, this may (or may not) be interesting for you. For MVC we identified a few locale-dependent aspects which we had to support:
To support these scenarios we defined the term "request locale" as the locale which is used for any locale-dependent operation within the lifecycle of a request. The request locale is resolved for each request using the following SPI: public interface LocaleResolver { Locale resolveLocale(LocaleResolverContext context); } The default implementation basically resolves the locale by parsing the Accept-Locale request header and resolving the locale with the highest priority. But developers can customize this by providing their own resolver. So if the developer wants to support only a specific subset of locales, he could simply create a custom resolver and match the supported locales against the Accept-Locale header as described in Pavel's previous mail. You can see the full SPI here: All the details are described in the MVC spec document (pages 37-38): I'm not sure if anything described here could be useful for JAX-RS. Of cause we (the MVC EG) would be happy to see any of our APIs to be integrated into JAX-RS. Christian
|
|
Hi Christian,
The default implementation basically resolves the locale by parsing theThis seems very useful, pretty much like what could be useful within JAX-RS itself. That selected Locale could then be used with a specifically set up message interpolator, just as JSF defines this integration with Bean Validation. Out of curiosity, how is that priority be defined? --Gunnar 2017-05-28 16:00 GMT+02:00 Christian Kaltepoth <christian@kaltepoth.de>: Hey Pavel,The struggle here is with the SupportedLanguagesProvider - it feels like
|
|
Hi Gunnar, sorry, the term "priority" was a bit misleading in this context. Actually it uses the "quality value" from the "Accept-Language" header. Christian 2017-05-29 14:26 GMT+02:00 Gunnar Morling via Groups.Io <gunnar.morling@...>:
Hi Christian, --
|
|
I see, thanks for clarifying the details, Christian!
toggle quoted messageShow quoted text
To me it seems that'd be a very reasonable default behaviour for JAX-RS; people still could plug in a custom LocaleResolver based on their custom requirements and context, e.g. preferring a Locale for which they provide a resource bundle with validation messages. 2017-05-29 15:36 GMT+02:00 Christian Kaltepoth <christian@kaltepoth.de>:
Hi Gunnar,
|
|