@ManagedProperty with request parameter not set in a @Named bean
Asked Answered
M

2

7

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.

Manon answered 28/2, 2015 at 9:12 Comment(2)
have you tried to change RequestScoped on ViewScoped?Babbler
CDI doesn't provide out-of-the-box request parameter injection (and you can't use what you have because JSF won't inject into a CDI context, although the reverse is possible). Look at this answerRundell
A
9

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

Alboin answered 2/3, 2015 at 6:3 Comment(0)
B
0

The question and the accepted answer are very old. Nowadays, with Jakarta Server Faces, you can use @ManagedProperty with @Inject in a @Named bean:

@Inject @ManagedProperty("#{param.key}")
private String key;
Blowzy answered 13/2 at 16:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.