Question

What Weld CDI can @Inject without declaring a @Produces in JSF 2.1+ application?

As I understand, it can inject FacesContext in properly set up web application.

Can it inject:

  • HttpSession?
  • context-param from web.xml (ala ServletContext.getInitParameter(xxx))
  • env-ref from web.xml
Was it helpful?

Solution

As far as I tested (and also according to the Weld Spec 1.1) you can inject javax.security.Principal and javax.transaction.UserTransaction in Java EE environment. This works for me fine on JBoss AS 7.2 with CDI version 1.1-PRD.

And for the Servlet container, it is it's responsibility to make these objects injectable for your application

  • javax.servlet.http.HttpServletRequest
  • javax.servlet.http.HttpSession
  • javax.servlet.ServletContext

However, not every container can really support this (and also I didn't test this but I suppose it should work - I've already seen this code somewhere).

OTHER TIPS

Ok, here is my own answer to this question.

There is incubating Apache project DeltaSpike.

DeltaSpike consist of a number of portable CDI extensions that provide useful features for Java application developers.

According to the documentation, the Servlet module allows injection of ServletContext, HttpSession and Principal objects.

However, I have taken a different path and implemented context parameter injection myself, using @Producer method with InjectionPoint argument. It is rather simple really.

First create a annotation for parameter which will hold context-param name attribute.

@Qualifier
@Target({ ElementType.FIELD, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface WebContextParameter {
    @Nonbinding String value() default "";
}

Annotation attribute name() must be declared as @Nonbinding so CDI will not use it as part of qualifying process.

Second, create producer bean with @Produce method

public class WebContextParameterProducer {
    @Inject
    private ServletContext context;

    @Produces
    @WebContextParameter()
    public String createWebContextParameter(InjectionPoint ip) {
        WebContextParameter annotation = null;
        for (Iterator<Annotation> it = ip.getQualifiers().iterator(); it.hasNext();) {
            Annotation n = it.next();
            if (n.annotationType().equals(WebContextParameter.class)) {
                annotation = (WebContextParameter) n;
                break;
            }
        }       

        return context.getInitParameter(annotation.value());
    }
}

After that, use anywhere in your code:

@Inject
@WebContextParameter("my.config.option")
String myConfigOption = "default-value";

Please note, however, the "default-value" will be used only in non CDI environment. In CDI, myConfigOption will be set to null if no value will be found in web.xml. This example can be expanded adding additional defaultValue() attribute to annotation to alleviate this.

So basically, ServletContext is already @Inject-able, so the rest of the stuff from it is injectable too.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top