Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [jaxrs-dev] Integrating JAX-RS, CDI and bean validation

Replying to myself:

Actually we probably can do without RequestLocale interface by making getLocale() a producer method and requiring the default validator factory to use the Locale if it is available through injection in the CDI spec.

Adding a @Produces method to the getLocale() method should then be enough:

@RequestScope
public UserRequestLocaleProducer {
    @Inject
    private HttpHeaders headers;

    @Produces @JaxRs  
    public Locale getLocale() {
        return getLocaleFromHeaders(headers.getAcceptableLanguages());
    }
}

In that case a Locale should probably always be available for injection (defaulting to Locale.getDefault() if no producer is available).

Best regards,
  Niklas


2018-03-02 23:08 GMT+01:00 Niklas Mehner <niklas.mehner@xxxxxxxxx>:


2018-03-01 17:52 GMT+01:00 Santiago Pericas-Geertsen <santiago.pericasgeertsen@oracle.com>:

[...]
 
 Unfortunately, I’m not sure if there is an elegant way to support this use case at the moment (and I think the reason why this was brought up in the context of MVC), but we should definitely make this a high priority. 

 I’m not sure what’s the best solution yet, but if is using a ValidatorFactory, then perhaps a ContextResolver could be used just like for a JAXBContext as a way to configure the runtime.

— Santiago


The easiest/cleanest solution I can come up with is to have a RequestLocale interface:

package jakarta.enterprise.i18n;

public interface RequestLocale {
    Locale getLocale();
}

and updating the CDI Spec to require the default validator to use the RequestLocale if it is available in the current CDI scope.
By default this would not change any validation behavior, since no RequestLocale exists.

For a developer there are two use-cases:

1. specify a global RequestLocale for all requests. E.g.

@RequestScope
public UserRequestLocale implements RequestLocale {
    @Inject
    private Principal principal;
   
    public Locale getLocale() {
        return getLocaleForPrincipal(principal);
    }
}

2.) specify a RequestLocale for one environment (JAX-RS, MVC, JSF, Servlet) by using a qualifier. E.g.:

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({FIELD, METHOD, TYPE, PARAMETER})
public @interface JaxRs {
}

@RequestScope
@JaxRs
public UserRequestLocale implements RequestLocale {
    @Inject
    private HttpHeaders headers;
   
    public Locale getLocale() {
        return getLocaleFromHeaders(headers.getAcceptableLanguages());
    }
}

This way the implementation can be sure that the HttpHeaders are available.

The JAX RS spec could state that:
    - If a global RequestLocale exists nothing is done since the RequestLocale is automatically used by validation.
    - Otherwise the implementation adds a global RequestLocale to the request scope that delegates to the @JaxRs specific RequestLocale implementation.
   
A default implementation could be added to the api and it could be activated using the alternatives in the beans.xml:

<beans>
  <alternatives>
        <class>javax.ws.rs.i18n.DefaultHeadersRequestLocale</class>
  </alternatives>
</beans>

This solution could perhaps work for all specs and perhaps solve other problems involving a user locale as well. What I have no idea about is which specification the RequestLocale could possibly live in.

Could this be a viable way of solving this?

Best regards,
  Niklas
 


Back to the top