Caelum | Ensino e Inovação - Cursos de Java, Scrum, Ruby on Rails


Java EE 6: Começando com Bean Validation

Por Lucas Souza em 03/02/10

Não existe tarefa mais comum hoje em dia do que validar dados em uma aplicação. Por exemplo, validamos se na camada de apresentação o usuário preencheu algum campo obrigatório, depois fazemos a mesma lógica de validação em nossa regra de negócio e por último validamos se os dados que serão salvos no banco também estão corretos. O que na maioria das vezes os desenvolvedores fazem é validar estas regras em todos os lugares, e muitas vezes resulta em validações complicadas e possíveis erros na aplicação. Muitos desenvolvedores consideram essa tarefa enfadonha.

Na nova versão do Java EE lançada dezembro de 2009 existem grandes novidades: Servlets 3.0, JAX-RS, CDI, JSF 2.0 e a Bean Validation, definida pela JSR 303. Com a Bean Validation é possível realizarmos validações atráves de metadados (anotações) e as utilizarmos em todas as camadas de nossa aplicação.

Podemos até mesmo criar nossas próprias regras de validações e aplicarmos em outros pontos do nosso sistema. Essas regras podem ser facilmente integradas com JPA e JSF, por exemplo. Vamos considerar uma classe que represente um contato:


public class Contato {

  private String nome;

  private String email;

  // getters e setters

  public void enviaEmail() {
    // codigo envio de email
  }
}

E vamos adicionar nossas regras de validação utilizando a Bean Validation:


public class Contato {

  @NotEmpty
  @Pattern(regexp = ".+@.+\\.[a-z]+")
  private String email;
   
  @NotEmpty
  private String nome;

  // getters e setters

  public void enviaEmail() {
  // codigo envio de email
  }
}

A anotação @NotEmpty garante que o email não poderá ser vazio assim como o atributo nome. No atributo email também colocamos a anotação @Pattern, onde podemos passar qualquer expressão regular, que o Bean Validation validará o valor passado ao atributo nome com a expressão regular.

Lembrando que o Bean Validation é uma especificação e como toda especificação, para utilizarmos precisamos de uma implementação para a utilizarmos. A implementação usada nos exemplos é a Hibernate Validator, e é a implementação de referência.

Integrando com o JSF

O código abaixo mostra um formulário simples utilizando JSF, que chama um método enviaEmail do ManagedBean quando clicamos no botão “EnviaEmail“:

<h:form id="formulario">
     <h:panelGrid columns="3">
          <h:inputText id="email" value="#{contato.email}"/>
          <h:message for="email" styleClass="error"/>
          <h:commandButton action="#{contato.enviaEmail}"
               value="Enviar Email"/>
     </h:panelGrid>
</h:form>

Precisamos ainda anotar nossa classe Contato com @ManagedBean(name="contato") e @RequestScoped para que a mesma seja um ManageBean e consiga integrar-se com o JSF.
Quando clicarmos no botão “Enviar Email” automaticamente será validado se o atributo email foi preenchido a atende a expressão regular da anotação @Pattern.

Podemos muitas vezes nos deparar com algum caso onde é necessário fazermos uma validação um pouco mais específica, algo que não esteja implementado por padrão no Bean Validation. Validar um CEP seria um bom exemplo. O primeiro passo para fazermos nossa própria validação é criar uma anotação que sugira o nome desta validação.


@Constraint(validatedBy = CepValidator.class)
@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Cep {
  
  String message() default "Cep inválido";
  Class<?>[] groups() default { };
  Class<? extends Payload>[] payload() default { };

}

Reparem que em nenhum momento fizemos de fato a validação se o CEP é válido ou não. Por isso anotamos a anotação CEP que acabamos de criar com @Constraint e setamos o atributo validatedBy com a classe que está nossa validação realmente.
O próximo passo é criarmos a classe CEPValidator que fará a validação. Esta classe tem que obrigatóriamente implementar a interface javax.validation.ConstraintValidator:


public class CepValidator implements 
            ConstraintValidator<Cep, String> {

  private Pattern pattern = 
          Pattern.compile("[0-9]{5}-[0-9]{3}");

  @Override
  public void initialize(Cep constraintAnnotation) {

  }

  @Override
  public boolean isValid(String value, 
           ConstraintValidatorContext context) {
    Matcher m = pattern.matcher(value);
    return m.matches();
  }

}

No método isValid verificamos e retornamos um booleano dizendo se a String passada como argumento está de acordo com a expressão regular que criamos no topo da classe. Podemos agora validar qualquer atributo de algum Java Bean, devendo apenas anotar o atributo com a nossa recém criada @CEP. Por exemplo:


public class Contato {

  @Cep
  private String cep;

  // getters e setters
}

Para rodar esse exemplo precisamos de um servidor de aplicação compatível com o Java EE 6, como o Glassfish 3.0. A premissa do Bean Validation é que muitos outros frameworks acabem por adotar um único mecanismo de validação, sendo possível reaproveitar o código criado aqui. O Caelum Stella, que fornece diversos validadores para sistemas que envolvem o domínio brasileiro, em breve será compatível com essa especificação, possibilitando que você utilize-o em todas as diversas especificações que compões o Java EE.

Além disso precisamos de um Servidor de Aplicação compatível com a versão 6 do Java EE. Por enquanto o único servidor que implementa essa versão é o Glassfish v3.0 que por sinal também é uma implementação de referência.

  • Share/Bookmark

HTML, CSS, Javascript e UX na nova formação da Caelum

Por Anderson Leite em 29/01/10

A nova formação da Caelum tem o objetivo de aprofundar os conhecimentos numa área em constante crescimento. A formação tem a parceria da Locaweb e é composta dos cursos WD-41 | Design de Interação, Experiência do Usuário e Usabilidade e WD-43 | Desenvolvimento Web com HTML, CSS e JavaScript.

formacao_wd

User Experience

Ao navegar na web, sacar dinheiro de um caixa eletrônico ou mesmo usar um celular, nos deparamos com sistemas diferentes, escritos em Java, Ruby ou C#, porém nossa satisfação não é definida pela linguagem utilizada, e sim pela qualidade e facilidade em interagir com o produto: nossa experiência como usuário.

Ao estudo dessa interação usuário-produto dá-se o nome User Experience, muito conhecido como UX, e em português traduzido como Experiência do Usuário.

elements-of-user-experience

Pode-se definir User Experience como a satisfação e qualidade em interagir com a interface de um serviço, produto ou sistema. Muitos consideram a Experiência do Usuário como um dos principais fatores no sucesso ou fracasso de um software. O quanto seu software é focado na necessidade do usuário? Com que velocidade ele atende aos clientes? Quais as dificuldades para finalizar uma compra? Quanto mais simples de usar, menor é a necessidade de suporte e maior a viabilidade financeira do projeto. Podemos citar exemplos clássicos, como o GMail, que revolucionou a forma de utilizar email online, além do iPod com sua interface simples e objetiva.

Design de Interação

Um dos papéis que existem no processo de desenvolvimento da Experiência do Usuário é o de Designer de Interação. Existem diversas funcionalidades implementadas em um sistema que muitas vezes os usuários finais desconhecem ou tem pouco interesse, sendo que elas poderiam facilitar tarefas e otimizar tempo. O Designer de Interação se preocupa com as relações humanas de um software.

Autores e profissionais se referem ao Design de Interação como iD ou IxD (Interaction Design), existindo já uma associação oficial, a IxDA. No Brasil há um conhecido blog da Locaweb focado em Experiência do Usuário.

Designer de Interação x Arquiteto de Informação

Nos projetos web os dois papéis são parecidos, porém com diferentes focos. O Arquiteto de Informação se preocupa mais com o armazenamento e distribuição da informação, enquanto o Designer de Interação tem a responsabilidade de definir como essa informação será manipulada e transformada.
user_experience_garrett
É comum em equipes grandes o Designer de Interação ser responsável por criar wireframes enquanto o Arquiteto de Informação cria a estrutura e faz o planejamento geral.

Existe um instituto sobre Arquitetura de Informação e no ano passado o Brasil sediou o Interaction South-America 09.

Programador de Interfaces

E quem realmente escreve o código das interfaces web depois de planejadas? Nessa etapa entra o profissional com conhecimentos aprofundados de HTML, CSS, Javascript, que têm ganhado muita atenção nos últimos anos, em especial o Javascript, sendo reconhecido como uma linguagem extremamente poderosa e divertida. Esse profissional é focado em transformar o trabalho planejado pelos profissionais acima em realidade. Ter o domínio dos melhores padrões, layouts e conhecimento dos diversos navegadores existentes para converter o projeto em realidade são algumas das funções do Programador de Interface, também chamado de Web Designer.
web-design

O sucesso de um projeto dependente muito de atender e se possível superar as expectativas dos usuários, fazer com que a interação deles com o sistema seja tão satisfatória a ponto de atingir completamente os objetivos do sistema.

Confira o conteúdo dos treinamentos WD-41 | Design de Interação, Experiência do Usuário e Usabilidade e WD-43 | Desenvolvimento Web com HTML, CSS e JavaScript.

  • Share/Bookmark

Integração contínua: deploys e aprovações sem dor de cabeça para o cliente

Por Guilherme Silveira em 18/01/10

Em 2008 comentamos sobre a importância de integração contínua no processo de receber feedback rápido sobre suas mudanças em um sistema e depois sobre os problemas que surgem quando um sistema possui baterias de teste muito grandes e complexas.

Um das grandes vantagens da agilidade consiste em poder efetuar mudanças sem medo e receber as respostas rapidamente em relação aos bugs que introduzimos no sistema, evitando mais erros e, para atingir esse objetivo, um servidor de integração contínua deve integrar o nosso código com aquele existente e rodar a bateria de testes automatizados a cada commit, criando um relatório do que foi feito que pode ter quebrado a aplicação.

Existem diversos níveis de adoção de um servidor de integração contínua em um projeto, indo do mais básico que envolve a simples compilação de um projeto (quando a linguagem é compilada) e a execução de testes unitários, até cenários mais complexos. Uma das principais dores de cabeça que um cliente enfrenta, mesmo em empresas que adotam metodologias ágeis como XP e Scrum, está ligada ao produto ser colocado em produção e não funcionar: a famosa frase “mas no meu computador funcionou”.

Um cenário clássico envolve o desenvolvimento de testes unitários, que são rodados na máquina do desenvolvedor e no servidor de integração contínua. O desenvolvedor chama então o cliente para testar em sua máquina, que aprova a funcionalidade e depois de duas semanas é feito o deploy da aplicação quando, para a surpresa do cliente, ela não funciona como esperado.

Acontece que a máquina de desenvolvimento em geral não possui a mesma configuração – software de banco de dados, servidor, proxies, firewall ou até mesmo os dados contidos no banco – que o sistema em produção, e mudanças do gênero podem significar resultados completamente diferentes para o cliente que, no fim da iteração, não obtém o valor que esperava.

A solução está em criar um sistema de homologação e diversas empresas adotam essa prática. A dificuldade encontrada nessa etapa é a da não automatização do processo de réplica da estrutura e dados de produção para homologação. Dados antigos ou inadequados no ambiente de aprovação facilitam um aceite errôneo por parte do cliente no momento do teste. Na Caelum e em nossos clientes que possuem sistemas que efetuam deploy diversas vezes em um ano, para garantir a competibilidade da empresa, é comum automatizar o processo de deploy ao ponto de maximizar as semelhanças entre produção e homologação, e minimizar as idas e vindas de uma funcionalidade.

Passo a passo junto com o cliente, cada fase é incluída no pipeline de integração contínua. Primeiro o projeto é compilado, depois os testes unitários são executados. Essas duas fases do pipeline são padrão para linguagens compiladas como Java. Em algumas empresas devido ao código legado ter um acoplamento muito alto, essa primeira fase já envolve mudanças na maneira de trabalhar e na qualidade do código gerado pelos desenvolvedores.

As fases seguintes variam bastante de acordo com projeto, mas para melhorar o deploy que minimize o número de tentativas de aprovação é importante adicionar três fases: testes end-to-end automatizados, deploy para homologação e para produção em um clique.

Na primeira fase, os testes executam as funcionalidades como o cliente faria e cobrem a maior quantidade de funções plausíveis de automatização. Na segunda fase, os desenvolvedores podem optar por deployar para um sistema de homologação, onde o cliente aprovará com os dados copiados de produção (alterações ligadas a sigilo de dados devem ser aplicadas).

Por fim, quando o sistema está aprovado em homologação, com um clique o desenvolvedor efetua o deploy para produção. Nesse instante, os sistemas são restartados, de preferência com o uso de load balancers que permitem o restart sem a queda da aplicação, e o cliente está pronto para usar as funcionalidades novas.

Toda essa automatização tem um custo inicial de desenvolvimento que é compensado com a minimização de erros humanos no processo de deploy e na lentidão do mesmo. Muitas vezes o processo de deploy para qualquer um dos dois ambientes não é feito tão frequentemente devido ao processo ser demasiadamente complexo para ser executado manualmente. A chance de funcionar em produção é maximizada uma vez que a mesma foi testada em homologação com uma cópia mais fidedigna do sistema de produção possível: menos reclamações e tempo perdido pelo cliente.

Note que nenhuma ferramenta específica é necessária para adotar essa prática, basta mudar o método de trabalho.

  • Share/Bookmark

Nova versão da Apostila FJ-28 liberada com VRaptor 3.1

Por Lucas Cavalcanti em 13/01/10

Depois de mais de 4000 downloads nesses 3 meses de vida, lançamos o VRaptor 3.1 com muitas novidades e bugfixes, com destaque ao suporte aos novos recursos das servlets no Java EE 6, o que permite usar o VRaptor 3 sem nem mesmo um web.xml em containers compatíveis com servlets 3.0, além de novos recursos para AJAX, lógicas genéricas e facilidades no mapeamento de URLs, forwards e redirects.

vraptor apostila

Aproveitando o lançamento dessa nova versão do framework, estamos disponibilizando a atualização da apostila do curso FJ-28 de VRaptor, Hibernate e AJAX, que já está disponível para download. O material não abrange apenas VRaptor, Hibernate e JSP, mas também entra em detalhes de como fazer a costura de maneira correta, gerenciando suas Sessions, Transactions, etc, através da criação de uma webapplication desde o zero.

  • Share/Bookmark

Java EE6: Começando com as Servlets 3.0

Por Adriano Almeida em 08/01/10

Se você nunca escreveu uma servlet antes por causa do medo de tantas configurações, agora é o momento para iniciar nessa tecnologia. Repare, com esse artigo, como ficou mais simples desenvolver para a web com Java.

Grande parte das aplicações atualmente desenvolvidas em Java são para a Web e geralmente são desenvolvidas através de frameworks como Struts, VRaptor e JSF. No entanto, é muito importante que antes de aprendermos alguma dessas ferramentas, entendamos os conceitos que elas nos abstraem.

Servlets

O principal pilar do desenvolvimento Web em Java é a API de Servlets. Com ela é possível executarmos código de uma determinada classe Java a partir de requisições HTTP para uma URL. Esse acesso é feito através de configurações não triviais de um servidor e arquivos específicos, de maneira diferente às antigas linguagens de script, como Perl, o que pode tornar o aprendizado de Servlets complicado.

Até a versão 2 da API de Servlets, precisamos fazer a declaração dessas classes através de XML (o web.xml). Portanto, além de nos preocuparmos em escrever o código Java com o processamento e lógica que desejamos fazer, ainda temos que nos preocupar com as configurações em XML, numa estrutura de diretórios especifica (o famoso diretório WEB-INF/classes), além de ter de manusear um servlet container.

Pronto pra escrever sua primeira servlet? Use a versão 3.0!

No mês passado foi aprovada oficialmente a versão nova do JavaEE 6, trazendo entre várias especificações novas, uma versão para Servlets, contendo diversas atualizações, a JSR 315, também conhecida como Servlet 3.0.

Nessa nova versão criamos as Servlets da mesma forma que fazíamos antes, ou seja, através de uma classe que estenda HttpServlet. Dessa forma, podemos criar uma Servlet que recebe um parâmetro pela requisição e imprime o mesmo no console da seguinte forma:


public class OiMundo extends HttpServlet {
    protected void service(HttpServletRequest request, 
        HttpServetResponse response
        throws ServletException, IOException {
        
        String nome = request.getParameter("nome");

        PrintWriter out = response.getWriter();
        out.println("Ola: " + nome);
    }
}

A primeira grande diferença que pode ser percebida na Servlet 3.0 é o uso de anotações para a configuração das Servlets em vez de grandes declarações em XML. Na versão 3, existe a anotação @WebServlet, que indica que aquela classe é uma Servlet. Essa anotação recebe no seu parâmetro value em qual URL a Servlet estará disponível.


@WebServlet(value="/oiMundo")
public class OiMundo extends HttpServlet {
        PrintWriter out = response.getWriter();

Você já poderia acessar nossa Servlet através de uma URL semelhante a http://localhost:8080/projeto/OiMundo?nome=Caelum, porém é mais interessante termos um formulário HTML que enviará a requisição e o parâmetro para a Servlet. Podemos criar um oiMundo.html com o seguinte conteúdo:

<html>
  <body>
    <form action="oiMundo">Informe o nome:
      <input name="nome" type="text" />
      <input type="submit" value="Enviar" />
    </form>
  </body>
</html>

Desenvolvedores que já trabalharam com a versão 2 de Servlets podem perceber que não declaramos nenhum nome para nossa Servlet em sua configuração. Isso anteriormente era feito através da Tag <servlet-name> no XML. Porém, por padrão, na versão 3.0 é utilizado o nome completo da classe que está anotada. Podemos sobrescrever essa padrão através do parâmetro name da anotação @WebServlet:


@WebServlet(value="/oiMundo", name="ServletOiMundo")

Mais novidades da especificação

Além de não precisarmos mais fazer a declaração das nossas Servlets em XML, agora também podemos declarar Filtros via anotações com o uso de @WebFilter.

Outro ponto que também acaba sendo muito comum quando utilizamos frameworks e bibliotecas de terceiros é que se exige uma configuração mínima no web.xml dos nossos projetos. Mas agora nem mesmo precisamos fazer essa configuração. As bibliotecas podem disponibilizar no diretório META-INF de seus jars um arquivo chamado web-fragment.xml contendo as configurações mínimas necessárias para o funcionamento da biblioteca, dessa forma, nós que utilizamos as bibliotecas não precisaremos nem fazer as configurações mínimas.

O que preciso para usar a nova versão?

Para que possamos utilizar Servlet 3.0 em nossas aplicações precisamos de um servidor que implemente essa nova versão. Até o momento, o único servidor que possui um release compatível é o Glassfish v3. Outros servidores famosos como Jetty (disponível em versão experimental na versão 8) e Tomcat (planejado para a versão 7) também suportarão.

Agora bastaria disponibilizar um projeto no servidor contendo no seu diretório WEB-INF/classes o .class da nossa nova Servlet.

Servlet 3.0 e a Caelum

Nosso conhecido curso de java para web, que vai desde servlets e JSP até Struts 2 e um pouco de Hibernate e VRaptor, já incorpora essas novidades do Java EE 6, e agora possui um capítulo totalmente dedicado à API Servlet 3.0.

Além disso, a versão 3.1 do VRaptor possui suporte também através do uso dos web fragments, dessa forma, você utiliza o framework sem escrever absolutamente nenhuma linha de XML, nem mesmo a declaração do filtro do framework.

  • Share/Bookmark



Caelum | Ensino e Inovação
São Paulo: Rua Vergueiro, 3185, cj. 87, próximo ao Metrô Vila Mariana   |   Tel. (11) 5571-2751
Rio de Janeiro: Rua Senador Dantas, 80, cj. 307/308 - Centro   |   Tel. (21) 2220-4156 ou 2297-0033
Brasília: SCS Qd. 8 Bl. B-50, Sala 521 - Ed. Venâncio 2000   |   Tel. (61) 3039-4222