Remeber from the Inject
a Java logger via a CDI producer method post that the InjectionPoint can be
used to access metadata of the class where the artifact is injected. Based on
this statement, we can write a producer method capable to inject HTTP
parameters.
Typically, as a JSF developer you write a form like below:
<h:form>
Name: <h:inputText
value="#{playerBean.name}"/>
Surname: <h:inputText
value="#{playerBean.surname}"/>
<h:commandButton value="Register"
action="#{playerBean.registerAction()}"/>
</h:form>
The two fields, name
and surname are
declared in a bean private
and with some getters and setters:
@Named
@RequestScoped
public class
PlayerBean {
private static final Logger LOG =
Logger.getLogger(PlayerBean.class.getName());
private String name;
private String surname;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return
surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public void registerAction() {
LOG.info("Register: " + name +
" " + surname);
}
}
Well, nothing fancy here, and even a JSF novice can understand what
this code do just by looking over it in a second. But, now let's replace the <h:inputText/>
with simple HTML <input/>
as below:
<h:form>
Name: <input type="text"
name="name" id="name"/>
Surname: <input type="text"
name="surname" id="surname"/>
<h:commandButton value="Register"
action="#{playerBean.registerAction()}"/>
</h:form>
This time our getters and setters become useless, but we can still
obtain these two HTTP parameters like this:
FacesContext
facesContext = FacesContext.getCurrentInstance();
ExternalContext
externalContext = facesContext.getExternalContext();
ServletRequest
request = (ServletRequest) externalContext.getRequest();
request.getParameter("name");
request.getParameter("surname");
Now, let's generalize this case
in CDI style. Instead of writing request.getParameter("name");
we want to inject the HTTP parameter. For this, we start by defining a
qualifier and instruct the container to ignore the value:
@Qualifier
@Retention(RUNTIME)
@Target({METHOD,
FIELD, PARAMETER, TYPE})
public
@interface HttpParam {
@Nonbinding public String value();
}
Furthermore, we write the producer method as below - instead of
explicitly nominated the HTTP parameter name, we use the InjectionPoint metadata
features:
public class
HttpParams {
@Produces
@HttpParam("")
String getParamValue(InjectionPoint ip) {
//
obtain the current request
FacesContext
facesContext = FacesContext.getCurrentInstance();
ExternalContext
externalContext = facesContext.getExternalContext();
ServletRequest
request = (ServletRequest) externalContext.getRequest();
//
obtain the desired parameter
Annotated annotated = ip.getAnnotated();
HttpParam httpParam =
annotated.getAnnotation(HttpParam.class);
return
request.getParameter(httpParam.value());
}
}
Finally, we adjust the PlayerBean
to inject the desired HTTP parameters:
@Named
@RequestScoped
public class
PlayerBean {
private static final Logger LOG =
Logger.getLogger(PlayerBean.class.getName());
@HttpParam("name") @Inject String
name;
@HttpParam("surname") @Inject String
surname;
public void registerAction() {
LOG.log(Level.INFO, "Register: {0}
{1}", new Object[]{name, surname});
}
}
Done! Following this example you can inject any other HTTP parameter.
The complete example is available here.
Now, you can use this with <f:param/> or in place of <f:event type="preRenderView/> or <f:viewAction/>. In addition, you may be interested in converting and validating the HTTP parameters. Check out a great implementation from OmniFaces which is materialized in the CDI annotation @Param that allows us to inject, convert and validate a HTTP request parameter in a CDI managed bean.
Now, you can use this with <f:param/> or in place of <f:event type="preRenderView/> or <f:viewAction/>. In addition, you may be interested in converting and validating the HTTP parameters. Check out a great implementation from OmniFaces which is materialized in the CDI annotation @Param that allows us to inject, convert and validate a HTTP request parameter in a CDI managed bean.
Niciun comentariu :
Trimiteți un comentariu