Galera, estou fazendo dois tipos de validação
- Validações de tela (campo vazio, validacao de senha, etc…)
- Validações de Business ( do banco ) - checar se já existe matrícula para o mesmo aluno, por ex.
O código abaixo funciona! eu gostaria de saber se existe alguma forma melhor de se fazer as validações sem tem que repetir…
validator.addAll(errors);
validator.onErrorUse(Results.json()).withoutRoot().from(errors).serialize();
no código abaixo.
[code]public void save(final Enrollment enrollment) {
Enrollment enrollmentToUpdate = enrollmentBusiness.find(enrollment.getId());
List<Message> errors = new Validations(){{
that(enrollment.getStudent().getId() != null, "validation","studentNotSelected");
}}.getErrors(ResourceBundle.getBundle("messages"));
validator.addAll(errors);
validator.onErrorUse(Results.json()).withoutRoot().from(errors).serialize();
if (enrollmentToUpdate == null){
enrollmentToUpdate = new Enrollment();
enrollmentToUpdate.setCreateDate(new GregorianCalendar());
}
enrollmentToUpdate.setUpdateDate(new GregorianCalendar());
enrollmentToUpdate.setDayOfPayment(enrollment.getDayOfPayment());
enrollmentToUpdate.setGrade(enrollment.getGrade());
enrollmentToUpdate.setHasAddressProof(enrollment.isHasAddressProof());
enrollmentToUpdate.setHasBirthCertificate(enrollment.isHasBirthCertificate());
enrollmentToUpdate.setHasCPFXerox(enrollment.isHasCPFXerox());
enrollmentToUpdate.setHasFacePhotos(enrollment.isHasFacePhotos());
enrollmentToUpdate.setHasHealthPlanCard(enrollment.isHasHealthPlanCard());
enrollmentToUpdate.setHasLastYearSchoolDischarge(enrollment.isHasLastYearSchoolDischarge());
enrollmentToUpdate.setHasRegistrationNumberXerox(enrollment.isHasRegistrationNumberXerox());
enrollmentToUpdate.setHasVaccinationCard(enrollment.isHasVaccinationCard());
enrollmentToUpdate.setMonthOfEnrollment(enrollment.getMonthOfEnrollment());
enrollmentToUpdate.setShift(enrollment.getShift());
enrollmentToUpdate.setStudent(enrollment.getStudent());
try {
enrollmentBusiness.saveOrUpdate(enrollmentToUpdate);
} catch (final InvalidAttributesException e) {
errors.add(new I18nMessage("validation",e.getMessage()));
}finally{
validator.addAll(errors);
validator.onErrorUse(Results.json()).withoutRoot().from(errors).serialize();
}
ajaxRedirect("enrollment/list");
}[/code]
ao invés de fazer isso, muda para adicionar os erros diretamente no validator, e faça:
validator.onErrorSendBadRequest();
assim o status code da resposta vai ser 400 (assim vc não precisa fazer if lá no javascript) e os erros serão serializados em json (se a requisição veio pedindo json)
Ok,
essa sua sugestão eu já havia entendido mais ainda não tinha aplicado.
mas a questão é que tem erros que são de validação e tem erro que vem no
ai queria saber se tem alguma forma mais limpa de chamar o validador.
para não ter que repetir o mesmo código em cima e em baixo no catch.
Lucas muito obrigado, por toda a força que vc dá ao GUJ.
Vejo vc investindo muito tempo aqui. e vejo várias respostas pertinentes.
Valeu brother!!
adiciona todos os erros no validator. algo assim:
validator.checking(new Validations() {{
//validações aqui
}});
...
validator.add(<mensagem de erro>);
...
validator.onErrorSendBadRequest();
...
assim, e usando o snapshot que eu te mandei, ele vai fazer do jeito que vc precisa
Eu já fiz isso.
meu código atual.
[code]
public void save(final Enrollment enrollment) {
Enrollment enrollmentToUpdate = enrollmentBusiness.find(enrollment.getId());
validator.checking(new Validations(){{
that(enrollment.getStudent().getId() != null, "validation","enrollment.studentNotSelected");
}});
validator.onErrorSendBadRequest();
...
try {
enrollmentBusiness.saveOrUpdate(enrollmentToUpdate);
} catch (final InvalidAttributesException e) {
validator.add(new I18nMessage("validation", e.getMessage()));
validator.onErrorSendBadRequest();
}
result.use(Results.json()).withoutRoot().from("Matrícula salva com sucesso!").serialize();
}[/code]
O detalhe é que tenho que repetir o
Se colocar esse trecho apenas no catch. ele vai salvar o objeto mesmo que tenho erro de validação em cima. sacou?
O que está me incomodando é eu ter que repetir esse código acima.
Tem alguma forma melhor?
então, não tem muito o que fazer, pq qdo vc chama o validator.onErrorXXXX ele já verifica se tem erros e solta uma exception se tiver… vc precisa verificar se tem erros em dois momentos, então tem que chamar essa linha duas vezes mesmo, infelizmente…
na verdade na verdade o jeito que eu faria isso era ignorando esse try…catch no saveOrUpdate. Teoricamente vc deveria evitar esse erro dos InvalidAttributes com as validações anteriores, não é mesmo?
o que vc pode fazer também é usar o BeanValidations para fazer as validações no modelo, e então chamar
validator.validate(objeto);
antes de invocar o onErrorXXX
Eu checo no bussiness se já existe matrícula (enrrolment) para o aluno.
Acredito que se colocar no controller vou estar quebrando a arquitetura. não acha?
Pensei em colocar um método para validar o objeto no Business. ai eu chamaria no that.
Esse é o method do business:
[code]
public void saveOrUpdate(Enrollment t) throws InvalidAttributesException {
try{
session.beginTransaction();
Enrollment enroll = findByStudentId(t.getStudent().getId());
if (t.getId() == null && enroll != null){
throw new InvalidAttributesException("Já existe matrícula para este usuário");
}
Student student = studentBusiness.find(t.getStudent().getId());
t.setStudent(student);
session.saveOrUpdate(t);
session.getTransaction().commit();
}catch(InvalidAttributesException e){
session.getTransaction().rollback();
throw e;
}
}[/code]
não sei se estaria quebrando a arquitetura… vc pode fazer algo do tipo, no controller:
if (enrollmentBusiness.existsEnrollmentFor(student)) {
validator.add(new I18nMessage("student", "enrollment.exists"));
}