@ManagedProperty with request parameter not set in a @Named bean
cdi, http-request-parameters, jsf, managed-bean, managed-property
Solution
Using `@ManagedProperty` on a CDI managed bean works only when you're using JSF 2.3 or newer. You'll then need the `@ManagedProperty` annotation from `jakarta.faces.annotation`/`javax.faces.annotation` package instead of the `javax.faces.bean` one, and you need to use it in combination with `@Inject`.
import javax.inject.Inject;
import javax.inject.Named;
import javax.enterprise.context.RequestScoped;
import javax.faces.annotation.ManagedProperty;
// Use jakarta.* when you're already on JSF/Faces 3.0 or newer
@Named
@RequestScoped
public class ActivationBean {
@Inject @ManagedProperty("#{param.key}")
private String key;
@Inject @ManagedProperty("#{param.id}")
private Long id;
The `@ManagedProperty` annotation from the `javax.faces.bean` package works only in beans annotated with the legacy `@ManagedBean` annotation and has been deprecated since JSF 2.3 and removed since Faces 4.0.
In case you're still on JSF 2.2, or you just happen to already use the JSF utility library OmniFaces, then you can also use its `@Param` annotation instead. It automatically infers the parameter name and type from the Java field, hereby further reducing the boilerplate.
@Inject @Param
private String key;
@Inject @Param
private Long id;
Alternatively, you can also use the `<f:viewParam>` tag in the view for the purpose.
<f:metadata>
<f:viewParam name="key" value="#{bean.key}" />
<f:viewParam name="id" value="#{bean.id}" />
</f:metadata>
See also
- ViewParam vs @ManagedProperty(value = "#{param.id}")
- How do I process GET query string URL parameters in backing bean on page load?
- Backing beans (@ManagedBean) or CDI Beans (@Named)?
Problem
I've a CDI managed bean wherein I'd like to set request parameters as managed properties: ``` import javax.inject.Named; import javax.enterprise.context.RequestScoped; @Named @RequestScoped public class ActivationBean implements Serializable { @ManagedProperty(value="#{param.key}") private String key; @ManagedProperty(value="#{param.id}") private Long id; // Getters+setters ``` The URL is `domain/activate.jsf?key=98664defdb2a4f46a527043c451c3fcd&id=5`, however the properties are never set and remain `null`. How is this caused and how can I solve it? I am aware that I can manually grab them from `ExternalContext` as below: ``` Long id = Long.parseLong(FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("id"), 10); String key = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("key"); ``` However, I'd rather use injection.