O problema do input vazio no formulário

Numa aplicação web com muitos formulários, é muito comum existirem alguns campos de preenchimentos obrigatórios e outros não. E uma coisa que eu aprendi e que prezo muito nas aplicações é que tudo deve ser validado antes de chegar na regra de negócio em si. Não quero ficar tomando erros por conta de dados em estado inválido.

Uma situação curiosa que aconteceu comigo nesses dias é que tinha um cadastro onde o email precisava ser único para a entidade. É uma situação que acontece comumente em todas as nossas aplicações, outros casos clássicos são CPF, login de usuário etc. Criei até um validador da Bean Validation genérico para isso. Um ponto interessante nesse cadastro é que o email, por mais que precise ser único, não é obrigatório e, por conta disso, o usuário pode deixar o campo vazio.

E o campo texto vazio é onde mora o problema. Além de colocar a validação na aplicação, também criei a constraint para a coluna da tabela e, para ela, valor em branco é um valor que precisa ser único :/. Abaixo segue o código do meu validador genérico que deixa passar valores vazios.

	public class UniquenessValidator implements
			ConstraintValidator<ValidateUniqueness, Object> {

		...

		@Override
		public boolean isValid(Object target, ConstraintValidatorContext context) {
			UniquenessDao uniquenessDao = ApplicationContextHolder
				.instance.getBean(UniquenessDao.class);
			boolean valid = true;
			for (String fieldName : fieldNames) {
				Object fieldValue = getFieldValue(target, fieldName);
				if(fieldValue ==null || 
					!StringUtils.hasText(fieldValue.toString())) {
					continue;
				}

Para o banco não considerar a constraint, o valor sendo inserido precisava ser nulo. Caso você já tenha passado por essa situação, conte nos comentários como resolveu. A minha abordagem é sempre tentar usar um recurso do framework em questão, que para esse projeto foi o Spring MVC(quem diria..). Assim como qualquer framework web que se preze, o Spring MVC é cheio de converters para pegar os valores que vem do formulário e converter para os tipos necessários dos nossos objetos. Para ser bem sincero ele possui várias interfaces para tratar da conversão de valores, que foram surgindo com o passar do tempo.

O que precisamos fazer é basicamente registrar um conversor que já existe dentro do framework e que pode tratar textos vazios como Strings nulas :).

@Controller
@RequestMapping("/profissional")
@Transactional
public class ProfissionalController {

	...

	@InitBinder
	public void initBinder(WebDataBinder dataBinder) {
		...
		dataBinder.registerCustomEditor(String.class, "profissional.email",
				new StringTrimmerEditor(true));
	}

Perceba que fiz o registro para um @Controller específico. O código é feito dentro do método anotado com @InitBinder. O conversor usado em questão foi o StringTrimmerEditor, que recebe um boolean como argumento, indicando se ele deve tratar Strings vazias como nulo.

	public class StringTrimmerEditor extends PropertyEditorSupport {

		private final String charsToDelete;

		private final boolean emptyAsNull;

		public StringTrimmerEditor(boolean emptyAsNull) {
			this.charsToDelete = null;
			this.emptyAsNull = emptyAsNull;
		}

		public StringTrimmerEditor(String charsToDelete, boolean emptyAsNull) {
			this.charsToDelete = charsToDelete;
			this.emptyAsNull = emptyAsNull;
		}


		@Override
		public void setAsText(String text) {
			if (text == null) {
				setValue(null);
			}
			else {
				String value = text.trim();
				if (this.charsToDelete != null) {
					value = StringUtils.deleteAny(value, this.charsToDelete);
				}
				if (this.emptyAsNull && "".equals(value)) {
					setValue(null);
				}
				else {
					setValue(value);
				}
			}
		}

		@Override
		public String getAsText() {
			Object value = getValue();
			return (value != null ? value.toString() : "");
		}

	}

Essa é uma das coisas que gosto muito no Spring. Eles possuem certas implementações prontas, típicas de quem já passou por problemas comuns enquanto desenvolve uma aplicação.

Bom essa era um post mais simples, mas acho que pode ser útil para quem passar por uma situação parecida.

Advertisements

4 thoughts on “O problema do input vazio no formulário

  1. Oi Alberto,

    Não entendi bem o seu problema. Você quer que valores de inputs vazio sejam considerados pela aplicação como null? É isso?

    Outro dúvida, que servidor você está usando?

    Like

  2. Ufa, então acho que vc entendeu. Queria que vazio fosse nulo sim, para alguns cadastros… O servidor web é um tomcat padrão e um servidor de banco de dados é um mysql. É uma configuração parecida com a que existe para o JSF, só que no Spring MVC podemos geral ou por controller.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s