Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.3k views
in Technique[技术] by (71.8m points)

jsf 2 - Depedency inject request parameter with CDI and JSF2

When using CDI and JSF2 How can a HTTP request parameter be injected into a bean?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

HINT: before reading any further have a look at http://showcase.omnifaces.org/cdi/Param. Do it yourself is probably obsolete seeing how omnifaces is a de facto standard today. I would probably not have written this if omnifaces had this at the time

CDI does not solve specialized problems like injecting a request parameter. That's supposed to be solved by extensions.

This is already provided by solder. http://docs.jboss.org/seam/3/solder/latest/reference/en-US/html/injectablerefs.html

It will probably be included in Deltaspike 0.4-incubating or similar as well.

That said the code required is rather simple to implement yourself. Example below:

Annotation to use for the injection point (For example private String myParam;)

import javax.enterprise.util.Nonbinding;
import javax.inject.Qualifier;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;


@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER })
public @interface RequestParam {
    @Nonbinding
    public String value() default "";
}

Now we have the annotation but we can't just ask the container to dependency inject a @RequestParam - we obviously need an implementation.

import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.faces.context.FacesContext;
import javax.inject.Inject;

public class RequestParamProducer implements Serializable {

    private static final long serialVersionUID = -4260202951977249652L;
    @Inject
    FacesContext facesContext;

    // Producer for @RequestParam
    @Produces
    @RequestParam
    String getRequestParameter(InjectionPoint ip) {
        String name = ip.getAnnotated().getAnnotation(RequestParam.class)
                .value();

        if ("".equals(name))
            name = ip.getMember().getName();

        return facesContext.getExternalContext().getRequestParameterMap()
                .get(name);
    }
}

So how does it work? Well quite simply it first checks if you did specify what parameter you wanted as in @Requestparam("longAndTerribleFieldNameBestToSpecify");

If you didn't it will use the fieldName. So if you annoted a setter called setMyInstance it will look for a parameter called setMyInstance.

The normal use case would be to have a String variable that is named exactly like the parameter you want.

Note that we inject FacesContext, that must also be produced. A FacesContext producer could look like this:

class FacesContextProducer {

   @Produces @RequestScoped FacesContext getFacesContext() {

      return FacesContext.getCurrentInstance();

   }

}

End usage:

@Inject
@RequestParam
private String session_secret;

Note that this will not work for Servlet or similar as it requires access to FacesContext. In those cases one need to wrap the injection with for example a bean that is @RequesScoped. You inject that bean instead.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...