Depedency inject request parameter with CDI and JSF2

前端 未结 1 1636
南笙
南笙 2020-11-29 10:54

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

相关标签:
1条回答
  • 2020-11-29 11:08

    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.

    0 讨论(0)
提交回复
热议问题