Introducción
Usted puede hacerlo, pero los métodos JSF Ajax/acción/oyente son semánticamente el lugar equivocado hacer la validación. En realidad, no desea llegar tan lejos en el ciclo de vida JSF si tiene valores de entrada incorrectos en el formulario. Desea que el ciclo de vida JSF se detenga después de la fase de validación de JSF.
que desea utilizar una anotación de JSR303 Bean Validation (@NotNull
y amigos) y/o validador de restricción, o utilizar un JSF Validator
(required="true"
, <f:validateXxx>
, etc) para que en su lugar. Se invocará correctamente durante la fase de validaciones JSF. De esta forma, cuando la validación falla, los valores del modelo no se actualizan y la acción comercial no se invoca y usted permanece en la misma página/vista.
Como no hay una anotación de validación de Bean estándar o un validador de JSF con el fin de verificar si un valor de entrada dado es único de acuerdo con la base de datos, necesitaría actualizar un validador personalizado para eso.
Voy a mostrarle a ambos lados cómo crear un validador personalizado que compruebe la exclusividad del nombre de usuario.
personalizada JSR303 Bean Validation anotación
En primer lugar crear una anotación personalizada @Username
restricción:
@Constraint(validatedBy = UsernameValidator.class)
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
public @interface Username {
String message() default "Username already exists";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Con este validador restricción (nota: @EJB
o @Inject
dentro de un ConstraintValidator
funciona sólo desde CDI 1.1; así que si Todavía estoy en CDI 1.0 entonces que había necesidad de agarrar manualmente desde JNDI):
public class UsernameValidator implements ConstraintValidator<Username, String> {
@EJB
private UserService service;
@Override
public void initialize(Username constraintAnnotation) {
// If not on CDI 1.1 yet, then you need to manually grab EJB from JNDI here.
}
Override
public boolean isValid(String username, ConstraintValidatorContext context) {
return !service.exist(username);
}
}
Finalmente lo utilizan de la siguiente manera en el modelo:
@Username
private String username;
personalizado JSF Validador
Una alternativa es utilizar una costumbre Validador JSF Sólo implementar la interfaz JSF Validator
:
@ManagedBean
@RequestScoped
public class UsernameValidator implements Validator {
@EJB
private UserService userService;
@Override
public void validate(FacesContext context, UIComponent component, Object submittedAndConvertedValue) throws ValidatorException {
String username = (String) submittedAndConvertedValue;
if (username == null || username.isEmpty()) {
return; // Let required="true" or @NotNull handle it.
}
if (userService.exist(username)) {
throw new ValidatorException(new FacesMessage("Username already in use, choose another"));
}
}
}
Finalmente utilizarlo de la siguiente manera a la vista:
<h:inputText id="username" ... validator="#{usernameValidator}" />
<h:message for="username" />
Tenga en cuenta que normalmente tendría que utilizar una anotación de @FacesValidator
en la clase Validator
, pero hasta la próxima JSF 2.3 , no es compatible con @EJB
o @Inject
. Vea también How to inject in @FacesValidator with @EJB, @PersistenceContext, @Inject, @Autowired.
Creo que, en primer lugar, no debería redireccionar a otra página, a menos que el nombre de usuario sea válido. – Benchik