abu taha9
abu taha9

Reputation: 55

Java JSF About Custom Validation

i am using this way in custom validation i am little bit confused if this way is correct or not if i assumed that i have this form:

<h:form id="myForm>
 <h:outputText value="user name" />
 <h:inputText value="#userBean.userName" id="userName" />

 <h:outputText value="Password" />
 <h:inputText value="#userBean.Password" id="passwd" />
</h:form>

and i have its Managed Bean :

@ManagedBean(name="userBean")
@SessionScoped
public class UserBeanData{
   private String userName;
   private String password;
   // with setters and getters........
   //
}

and the custom validator to validate the Managed Bean field and the Implmentation like :

@Override
public validate(FacesContext context, UIComponent component, Object value) throws ValidatorException{
Map<String, String> params = context.getExternalContext().getRequestParametersMap();

String username = params.get("myForm:username");
String pass = params.get("myForm:passwd");

// validate : if fields are not null check if the user exists if the result is empty , throws a validation Message Error
}

My Question is : Retrieving the Managed bean values like this is true or not ????

Upvotes: 0

Views: 1727

Answers (2)

BalusC
BalusC

Reputation: 1109532

You're basically looking for the solution in the wrong direction. Validation is only applicable on the individual submitted values, e.g. minimum/maximum length, non-empty/null, regex pattern, etcetera. But you want to invoke a business action based on all submitted values: logging-in an user. This is not exactly input validation.

Just add required="true" to the both input components and perform the job in the action method.

E.g.

<h:form id="myForm>
    <h:outputText value="user name" />
    <h:inputText value="#{userBean.userName}" id="userName" />
    <h:message for="userName" />

    <h:outputText value="Password" />
    <h:inputSecret value="#{userBean.password}" id="passwd" />
    <h:message for="passwd" />

    <h:commandButton value="Login" action="#{userBean.login}" />
    <h:messages globalOnly="true" />
</h:form>

with

@ManagedBean
@RequestScoped
public class UserBean {

    private String userName;
    private String password;

    @EJB
    private UserService service;

    public String login() {
        User user = service.find(userName, password);

        if (user != null) {
            FacesContext.getCurrentInstance().getExternalContext().getSessionMap("user", user);
            return "home?faces-redirect=true";
        } else {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Unknown login"));
            return null;
        }
    }

    // ...
}

Upvotes: 1

Fritz
Fritz

Reputation: 10055

Pay attention to the validate method's firm. It has an UIComponent parameter that is the component validated by the method. This UIComponent has both the current value (getValue()) and the value that the user submitted (getSubmittedValue()).

You might have to cast that UIComponent to the particular type of component you're validating (int this case, it's an UIInput).

Now, if you're going to validate both username and password prior to a log in, there are several ways to do it. In your case, validating the username field with the password field as an added parameter should suffice. You can achieve that by doing this:

<h:outputText value="user name" />
<h:inputText value="#userBean.userName" id="userName" validator="#{yourBean.validateLogin}">
    <f:attribute name="pass" value="#{passwordField}" />
</h:inputText>

<h:outputText value="Password" />
<h:inputText value="#userBean.Password" id="passwd" binding="#{passwordField}"/>

Note that the binding in the password <h:inputText/> is related to the value of the pass of the <f:attribute/> tag nested in your username <h:inputText/>. With this setup, you can perform your validation like this:

public void validateLogin(FacesContext context, UIComponent component, Object value) throws ValidatorException {
    //I suppose it's a typo, but your validate method lacks the return type.
    String username = (String) value;
    UIInput passwordInput = component.getAttributes().containsKey("pass") ? 
        (UIInput) component.getAttributes().get("pass") : null;
    if(passwordInput != null) {
        //Just to be sure the input was added as a parameter successfuly
        String submittedPassword = passwordInput.getSubmittedValue();
        //Now, do your validations based on the strings "username"
        //and "password".
    }
}

Since all of this is being done in the validation phase, the values aren't set in your managed bean yet, that's why you have to play around a little with the submitted values.

Upvotes: 0

Related Questions