"Nossa história no início foi bem parecida com as histórias tradicionais. Sabe aquelas empresas que gastam uma semi-fortuna com uma consultoria para desenhar um processo de desenvolvimento de software? Assim estávamos nós no início de 2007. Poucos projetos eram entregues nas datas acordadas e muitos deles falhavam ou não satisfaziam as necessidades dos clientes. Contratar uma grande consultoria de software parecia ser uma boa tentativa de arrumar as coisas, mas o resultado do trabalho foi um documento que descrevia um processo com algumas centenas de páginas que devia ser seguido á risca, isso sem contar as dúzias de documentos padrão para todos os tipos de requisição e comunicação que se possa imaginar. Dezenas de páginas descreviam quem deveria falar com quem e quem entrega qual documento em qual momento. O processo foi feito para lidar com todas as complexidades, burocracias e exigências que nós mesmos criamos dentro da empresa."
Se você sentiu alguma identificação com esta estória, então leia o restante....
http://www.infoblogs.com.br/view.action?contentId=36535
http://blog.fragmental.com.br/2007/08/15/introduzindo-agilidade-num-ambiente/
Um pouco sobre internacionalização
Um pouco sobre internacionalização
Internacionalização também é conhecida por i18n devido as dezoito letras que estão entre a primeira e a última da palavra inglesa internationalization, é uma técnica utilizada para desenvolver softwares de maneira que o mesmo possa ser facilmente traduzido a outras línguas. Mas não só isso, um software internacionalizado deve ser adaptável o suficiente para se adequar a características regionais, legais, culturais e técnicas, tais como fuso horário, formato de números, datas, sistemas métricos e moedas. Este processo pode ser automático, ou manual.
Como há diferenças entre as diversas línguas “irmãs” como é o caso do português de Portugal e o do Brasil, é recomendável especificar estas diferenças. Para isto utiliza-se o l10n (da palavra inglesa localization) em conjunto do i18n, evidentemente os dois são complementares. O i10n adiciona características especificas de uma região.
Analogamente, quando criamos um objeto Locale desta forma:
Locale ptBR = new Locale(“pt”, “BR”);
Estamos dizendo que nossa língua é o português, mas que esta língua é especifica para o local Brasil. Mas, claro, se quisermos definir apenas a língua (i18n) podemos utilizar o construtor que recebe apenas a língua, como a seguir:
Locale pt = new Locale(“pt”);
Um software internacionalizado normalmente vem com um ou vários arquivos texto. Estes devem seguir o seguinte padrão:
MyResources.properties
MyResources_fr.properties
MyResources_fr_CH.properties
MyResources_pt_BR.properties
MyResources_en.properties
Para o arquivo de mensagens da listagem 6 ser reconhecida pela classe ResouceBundle, este deve seguir este mesmo padrão (nome + _ + língua + _ + pais + . + properties), ficando assim:
messages_pt_BR.properties
messages_enproperties
Caso não seja definida um Locale para o ResourceBoundle, este irá utilizar o que ele detectar que normalmente é o disponibilizado pelo Sistema Operacional.
Consulte a API de ResourceBundle para maiores detalhes.
Internacionalização também é conhecida por i18n devido as dezoito letras que estão entre a primeira e a última da palavra inglesa internationalization, é uma técnica utilizada para desenvolver softwares de maneira que o mesmo possa ser facilmente traduzido a outras línguas. Mas não só isso, um software internacionalizado deve ser adaptável o suficiente para se adequar a características regionais, legais, culturais e técnicas, tais como fuso horário, formato de números, datas, sistemas métricos e moedas. Este processo pode ser automático, ou manual.
Como há diferenças entre as diversas línguas “irmãs” como é o caso do português de Portugal e o do Brasil, é recomendável especificar estas diferenças. Para isto utiliza-se o l10n (da palavra inglesa localization) em conjunto do i18n, evidentemente os dois são complementares. O i10n adiciona características especificas de uma região.
Analogamente, quando criamos um objeto Locale desta forma:
Locale ptBR = new Locale(“pt”, “BR”);
Estamos dizendo que nossa língua é o português, mas que esta língua é especifica para o local Brasil. Mas, claro, se quisermos definir apenas a língua (i18n) podemos utilizar o construtor que recebe apenas a língua, como a seguir:
Locale pt = new Locale(“pt”);
Um software internacionalizado normalmente vem com um ou vários arquivos texto. Estes devem seguir o seguinte padrão:
MyResources.properties
MyResources_fr.properties
MyResources_fr_CH.properties
MyResources_pt_BR.properties
MyResources_en.properties
Para o arquivo de mensagens da listagem 6 ser reconhecida pela classe ResouceBundle, este deve seguir este mesmo padrão (nome + _ + língua + _ + pais + . + properties), ficando assim:
messages_pt_BR.properties
messages_enproperties
Caso não seja definida um Locale para o ResourceBoundle, este irá utilizar o que ele detectar que normalmente é o disponibilizado pelo Sistema Operacional.
Consulte a API de ResourceBundle para maiores detalhes.
Hibernate Validator
Hibernate Validator
A base para o JSR 303: Bean Validation.
Autor
Clayton K. N. Passos (netstart[@]gmail.com): Viciado em tecnologia. Atualmente trabalha como Desenvolvedor/Analista Pleno. (http://japz-j.blogspot.com)
A validação de dados pode e deve ser um processo centralizado e flexível o bastante para ser desempenhando em diferentes camfadas de um sistema, mas de forma centralizada. Utilizando o Hibernate Validator, inspiração para a JSR 303, isto pode ser uma tarefa simples.
Introdução
Validação de dados é uma tarefa comum, muitas vezes implementada em diferentes camadas, de diversas maneiras e até mesmo separado do framework de validação, consumindo tempo e causando erros difíceis de serem encontrados pela falta de centralização dos interesses (concerns).
Vários projetos vêm implementando e apresentando suas idéias no que diz respeito à validação de dados, entre eles: Struts, Spring e Hibernate. Neste artigo falaremos sobre a forma proposta pelo Hibernate 3, que é uma das inspirações para a JSR 303, uma das novas especificações prevista para o Java 7.
Nas primeiras versões do Hibernate 3, a API de validação estava junto do sub-projeto Hibernate Annotations, mas no momento da escrita deste artigo esta API encontra-se separada e leva o nome Hibernate Validator. Vale ressaltar que para a validação dos recursos aqui apresentados, utilizamos as próprias classes de teste do Hibernate Validator com algumas pequenas modificações e também os softwares e APIs nas seguintes versões:
· Hibernate Validator 3.0.0.GA;
· Hibernate Core 3.2.4.GA;
· Hibernate-Annotations 3.3.0.GA
· Eclipse 3.2.2;
· Java 1.6.0_01-b06.
Hibernate Validator
Seguindo o princípio da filosofia DRY (Don’t Repeat YourSelf), o Hibernate Validator trás uma forma de adicionar regras para validação automática de dados, de maneira que estas validações sejam implementadas uma e somente uma vez em toda a aplicação, eliminando a duplicação destas regras entre as diversas camadas (presentation, data access, database schema).
Utilizar annotations para adicionar regras é bastante conveniente e elegante, com elas podemos definir várias regras diretamente no modelo de classes persistente. O Hibernate Validator (H.V.) possuí algumas validações comuns (@NotNull, @Email, @Max, @Length, entre outras), mas não prende o desenvolvedor, possibilitando, a criação de validações personalizadas e internacionalizadas.
Cada annotation é associada a uma implementação de validação, que verifica se a instancia da entidade obedece a sua regra. O Hibernate faz isto automaticamente antes de um insert ou update, mas você também pode chamar a validação a qualquer momento em sua aplicação e de qualquer Java Persistence provider (JPA).
As validações podem ser utilizadas em dois níveis: aplicação e banco de dados. A primeira traz a possibilidade de validar a instancia de classes através de suas regras em tempo de execução (veja o quadro de constraints), enquanto que a segunda é incorporada ao Hibernate metamodel e ao database schema gerado, traduzindo as regras que você adicionou no mapeamento de suas entidades. Por exemplo, se você adicionar @NotNull a uma propriedade de sua entidade, a coluna irá ser declarada como not null no DDL schema gerado pelo Hibernate (hbm2ddl). Caso você não queria mais este comportamento, basta atribuir false a hibernate.validator.apply_to_ddl.
Este artigo está focado na primeira forma de validação.
Constraints
Aqui você pode ver uma lista de algumas regras que podem ser adicionadas a suas entidades, de maneira que o hibernate possa validar as informações armazenadas dentro delas. Lembre-se de que estas são constraints que o Hibernate Validator fornece para nós trabalharmos, mas podemos definir as nossas constraints personalizadas. Mas o que são constraints?Em poucas palavras: Constraints são regras de restrição, e sua semântica é definida pelas annotations que a descrevem.
Annotation Funcionalidade
@Length(min=, max=): Verifica se o tamanho da string esta dentro dos limites.
@Max(value=): Verifica se o valor é maior ou igual. Aplicado a representações de números, armazenados até mesmo em String.
@Min(value=): Verifica se o valor é menor ou igual. Aplicado a representações de números, armazenados até mesmo em String.
@NotNull: Checa se o valor não é null.
@NotEmpty: Checa se não é null e não vazia.
@Past: Checa se uma data esta no passado.
@Future: Checa se uma data esta no futuro.
@Pattern(regex=”regexp”, flag=)ou@Patten({@Pattern(...)}): Checa se a propriedade obedece à expressão regular.
@Range(min=, max=): Confere se o valor está entre o mínimo e o máximo (incluindo), aplicado a valores numéricos, mesmo armazenados em String.
@Size(min=, max=): Confere se a quantidade de elementos esta entre o mínimo e o máximo (incluído), aplicado a Array, Collection, Map.
@AssertFalse: Confere se o valor de uma propriedade boolean é false.
@AssertTrue :Confere se o valor de uma propriedade boolean é true
@Valid: Impõe uma validação recursiva aos objetos associados. Se o objeto é uma Collection, Map ou um Array, os elementos são validados recursivamente.
@Email: Confere se a string é um e-mail válido.
@CreditCardNumber: Confere se a string é um número de cartão de crédito válido.
@Digits: Verifica quantidade de dígitos ante e depois do separador de casa decimal (integerDigits e factionalDigits).
@EAN: Verifica se a string é um código EAN ou UPC-A válido
Como utilizar o framework?
É chegada a hora de “sujarmos as mãos” e ver como a teoria se aplica na prática. Lembre-se de que se você estiver utilizando o Hibernate como uma solução para o Mapeamento Objeto Relacional (ORM), a integração do Hibernate Core com o Hibernate Validador é transparente. As validações ocorrem sempre antes de qualquer insert ou update, caso haja algum erro será disparado uma exceção com as regras violadas. Se por algum motivo for necessário desabilitar a esta integração basta atribuir false a hibernate.validator.autoregister_listeners.
Para começar vamos criar uma classe que servirá apenas para nos mostrar os erros de uma forma mais amigável. Chamaremos esta classe de HandlerTest e seu propósito de existência é o de imprimir na saída padrão as mensagens de erro, se tiver alguma, caso contrário deverá nos avisar de que não há nenhum erro, veja a listagem 1.
Analisando o código, vemos que a classe HandlerTest verifica se o array de InvalidValue é igual a 0, esta é a forma da qual você pode ter certeza de que não nenhum erro foi detectado pelo Hibernate Validator, pois, sempre que for detectado um erro, haverá algum elemento no array retornado pelo validador. Caso o array invalidValues tenha algum elemento o código da listagem 1 chama o método print() para nos mostrar o quê tem dentro do array. Veja o quadro InvalidValue para saber a utilidade dos principais métodos desta classe.
InvalidValue
GetBeanClass(): Retorna o tipo da classe que provocou o erro.
getBean(): Retorna a instancia da classe que falhou na validação.
getMessage(): Retorna a mensagem de erro, que pode estar internacionalizada.
getValue(): Retorna o valor errado.
Como já dissemos, você pode validar as informações contidas em suas entidades, em qualquer lugar do sistema. A maneira de fazer isto é chamando o método getInvalidValues da classe ClassValidator, se houver algum erro na entidade ele retornará um array de InvalidValue contendo diversas informações pertinentes a este erro. Simples, não?
Agora que já temos uma maneira simples de verificar as validações, vamos a um caso de uso fictício, suponha que para a compra de um carro o mesmo deve obedecer a dois critérios, seu IPVA deve estar pago e livre de amassados. Definimos classe Car utilizando as Annotations @AssertTrue e @AssertFalse de maneira que a propriedade ipvaPago seja igual a true, e que a propriedade amassado seja igual a false, veja a listagem 2.
Listagem 2: Classe Carro
Na listagem 2 podemos observar que as constraints foram adicionadas em cima da propriedade, uma alternativa caso seja necessário é definidas sobre o método get da respectiva propriedade. Particularmente não gostamos de definir as regras em cima dos métodos getXX(), pois torna o código menos intuitivo e menos legível, aconselhamos que sempre utilize a propriedade para adicionar as constraints.
Acompanhe na listagem 3, que a classe AssertTest imprimirá primeiramente dois erros, mas posteriormente, como não será detectado nenhum erro pelo validador, apenas haverá uma mensagem confirmando que as informações contidas na entidade são válidas. Como não definimos nada no código referente a língua, as mensagens de erros virão na língua configurada no Sistema Operacional. Até o momento da escrita deste artigo, eram onze as línguas suportadas, entre elas: português do Brasil; inglês; espanhol; italiano; francês; chinês e alemão.
Lista 3: Classe AssertTest
Definindo suas próprias validações
Criar nossas próprias validações é muito simples, é necessário apenas duas coisas, criar uma Annotation que descreva a regra e criar uma classe que implemente a interface org.hibernate.validator.Validator (veja a listagem 4 e 5), feito isto é só adicionar a Annotation a sua entidade para que ela seja validada.
Listagem 4: Annotation Phone
Na listagem 4, podemos acompanhar o código de uma Annotation destinada a validação de telefones. Três pontos importantes devem ser observados nesta classe. Na primeira linha temos a anotation @ValidatorClass dizendo que é utilizado a classe PhoneValidator como a implementação que irá validar a entidade anotada com @Phone. Os dois próximos pontos importantes são as propriedades ddd e message. Ambas podem ser mudadas no momento de definir uma entidade da seguinte forma:
@Phone(ddd = “45”, message = “mensagem de erro”)
A propriedade message tem propósito especifico, que é armazenar uma string que será utilizada caso um erro proveniente desta Annotation seja detectada. No exemplo, o valor default é {validator.phone}, uma mensagem nada inteligível, mas aliado ao recurso de internacionalização ela será, pois com esta chave o mecanismos de internacionalização do Hibernate Validator tentará encontrar a mensagem apropriada, caso não encontre será utilizado a string {validador.phone} na integra.
A classe PhoneValidator mostrada na listagem 5, possuí apenas dois métodos reescritos da interface Validator. Enquanto o método initialize(Phone parameters) recupera os valores atribuídos na entidade para a annotatoin @Phone o método isValid(Object value) faz o trabalho de verificar se o conteúdo da propriedade é valido, atente para o parâmetro que isValid recebe, esta é a informação que deve ser validada. Em nosso código de exemplo para um telefone ser válido é preciso estar no formado (44)0000-0000 (DDD 44 entre parênteses, seguido de quatro números, um traço e novamente quatro números).
O Hibernate Validator utiliza a classe ResourceBundle para internacionalizar as mensagens de erros. É bastante tranqüilo trabalhar com ela, primeiramente precisamos de um arquivo .properties, dentro dos padrões (veja o quadro: Um pouco sobre internacionalização); a Annotation precisa estar preparada para trabalhar com a mensagem internacionalizada e que seja explicitado que utilizaremos o arquivo específico para as mensagems.
Na listagem 6, temos um código completo, que imprime a mesma mensagem de erro em duas línguas diferente. Para isto foram necessárias apenas algumas linhas de código adicionais, veja que foi preciso passar no segundo parâmetro do construtor de ClassValidator um ResouceBundle que foi criado apartir de um Locale.
É possível sobrescrever as mensagens padrão do H.V., a regra é simples. Dentro do arquivo que você armazena as mensagens internacionalizadas, você adiciona a chave validator.nomedaannotation. Por exemplo, para mudar a mensagem da annotation @NotNull haverá no arquivo a seguinte chave:
validator.notnull=Erro, a propriedade não pode ser null
Se for necessário informar os valores permitidos, como é caso de @Length, podemos colocar o nome da variável entre chaves, desta forma, esta será trocada automaticamente pelo valor configurado na entidade. Veja o exemplo a seguir:
validator.length=Xii!! Deu erro no Length, os valores devem estar entre {min} e {max}
Listagem 5: Classe PhoneValidator
Listagem 6: Classe PhoneTest
Não se preocupe
O Hibernate Validator cuida de vários problemas comuns do desenvolvimento de software. Referencia circular, muito discutido no quesito qualidade de software, é um destes problemas, este tipo de situação, comum, levou a alguns brasileiros criarem um pluguin para o Eclipse chamado ByeCycle que auxilia a eliminar referencias circulares. Acompanhe pela listagem 7 que a entidade Contact nos diz que a entidade Brother também deve passar pela validação (@Valid), mas a Classe Brother faz o mesmo para com a classe Contact, isto poderia facilmente levar a um problema sério de referencia circular, mas isto não é algo do qual devemos nos preocupar, pois o H. V. sabe lidar com esta situação perfeitamente, nos permitindo usar estas classes.
Listagem 7: Referencia circular
É possível validar todos os elementos de uma Collection ou array facilmente, não é necessário nenhum recurso “informágico”. Basta adicionar a Annotation @Valid a estrutura que esta terá todos os seu itens validados. Acompanhe a listagem 8 que demonstra como uma classe TV pode ter o seu Map de Show verificado item a item pelo Hibernate Validator.
Listagem 8: iterable
Esta poderosa ferramenta nos permite também agregar várias expressões regulares, para validar uma única propriedade, acompanhe a listagem 9, observe que definimos duas E.R. e também personalizamos as mensagens que serão utilizadas para informar o usuário caso alguma destas regras sejam desrespeitadas.
Listagem 9: agregando E.R.
Integração com Hibernate
A utilização do Hibernate (core) propriamente dito em conjunto com o Hibernate Validator é feita através do Hibernate Annotation (ou Hibernate EntityManager) e neste caso a validação será automática, não será necessário nenhum código para chamar o validador, pois esta chamada ocorrerá antes de qualquer inserção de dados novos ou alterações (save ou update).
Para verificar este comportamento foi criado uma entidade chamada Linha, a ela demos alguns atributos e algumas regras para serem verificadas, como por exemplo @NotNull e @Length(max = 100). Também foram criadas as classes HibernateUtil e LinhaTeste, classes utilizadas para nos fornecer a Session e testar o comportamento de validação respectivamente.
Após a execução do teste dois tipos de exceções foram lançadas: org.hibernate.PropertyValueException e org.hibernate.validator.InvalidStateException ambas indicando problemas encontrados pelo Hibernate Validator, veja a listagem 11 e 12 para verificar um pequeno trecho da exceção.
Não é recomendável mas caso seja necessário, é possível desligar a pré validação atribuindo false a variável de configuração:
hibernate.validator.autoregister_listeners
Listagem 10: Classe LinhaTeste
Listagem 11: exceção lançada pela validação do Hibernate
Exception in thread "main" org.hibernate.PropertyValueException: not-null property references a null or transient value: org.hibernate.validator.test.hibernateIntegracao.Linha.codigo
...
Listagem 12: exceção lançada pela validação do Hibernate
Exception in thread "main" org.hibernate.validator.InvalidStateException: validation failed for: org.hibernate.validator.test.hibernateIntegracao.Linha
...
Camada de apresentação
JBoss Seam é um poderoso framework para a construção de aplicações Web 2.0, unificando e integrando tecnologias como: AJAX, JSF, EJB3, Java Portlets e BPM. Este projeto é desenhado para eliminar a complexidade destas arquiteturas, de maneira a possibilitar os desenvolvedores criar aplicações web simplesmente anotando classes POJOs [7].
JavaServer Faces é um framework MVC, também para desenvolvimento de aplicações Web, que permite o desenvolvimento de aplicações para internet ao estilo Delphi, (arrastando e soltando). Considerado por muitos, a última palavra em desenvolvimento Web, resultado obtido pela maturidade de tecnologias como JSP/Servlet (Model1), Model2 (MVC) e Struts.
Trabalhando juntas, as tecnologias JSF e JBoss SeamÔ pode-se disparar o processo de validação até a camada de apresentação usando as tags e , desta forma, enquanto as regras são expressas no model as mensagens de erro são apresentadas na view, sem duplicação para o usuário, um exemplo de utilização desta tag encontra-se na listagem 13, veja também documentação do JBoss SeamÔ para maiores detalhes.
Listagem 13: visualizando as mensagens de erro com JSF
JSR 303: Bean Validation
Bean Validation, já aprovada e prevista para a versão 7 do Java, deverá padronizar a definição de validadores, regras de validação e afins. Baseado em annotations e descritores XML, este novo recurso fornecerá em tempo de execução meios de checar e validar as propriedades de classes persistentes. Para validações mais comuns e simples, serão utilizadas annotations, enquanto casos mais complexos ou regras de negócios específicas utilizarão um descritor XML para configurar a validação [1].
Fortemente inspirada no Commons-Validator, Hibernate Validator e XWork Validation Framework, a JSR 303 poderá ser utilizada não somente em aplicações web, mas também em aplicações desktop e para a camada de persistência, permitirá o envio mensagens de erros internacionalizadas, e também a personalização através da classe ResourceBundle.
O líder deste sub-projeto (Hibernate Validator) é um dos membros da JSR 303, por isto podemos esperar que esta nova especificação do Java seja bem semelhante ao que descrevemos neste artigo.
Considerações Finais
Consistência de dados, testes e validação, são itens dos quais todos precisamos, mais cedo ou mais tarde a esta necessidade “bate nossa porta”, é nesta hora que precisamos tomar a decisão de qual tecnologia e estratégia adotar. O Hibernate Validator fornece um tratamento bem interessante, como ela é fortemente ligada a Bean Validation, acreditamos que vale, e muito, dedicar algumas horas para a pesquisa e aprendizado deste recurso, não somente porque é algo que está por vir no Java 7, mas porque este tende a ser um padrão no desenvolvimento de aplicações.
Para facilitar a vida do leitor, está disponível para download um projeto eclipse com os fontes utilizados para validar as informações contidas neste material. Nele você encontrara exemplos de validações, incluindo até mesmo algumas que não foram extensivamente exploradas neste texto. É importante ressaltar que muitos dos códigos foram retirados ou modificados dos próprios testes unitários (JUnit) do Hibernate Validator, por isto, caso o leitor queira ter acesso aos originais basta buscar direto na fonte.
Referências
[1] JSR 303: Bean Validation http://jcp.org/en/jsr/detail?id=303
[2] Hibernate - http://www.hibernate.org
[3] Commons-Validator - http://jakarta.apache.org/commons/validator
[4] XWork Validation Framework - http://wiki.opensymphony.com/display/XW/Validation+Framework
[5] API da classe ResourceBundle
[6] Internacionalization support - http://java.sun.com/javase/6/docs/technotes/guides/intl/index.html
[7] http://www.jboss.com/products/seam
A base para o JSR 303: Bean Validation.
Autor
Clayton K. N. Passos (netstart[@]gmail.com): Viciado em tecnologia. Atualmente trabalha como Desenvolvedor/Analista Pleno. (http://japz-j.blogspot.com)
A validação de dados pode e deve ser um processo centralizado e flexível o bastante para ser desempenhando em diferentes camfadas de um sistema, mas de forma centralizada. Utilizando o Hibernate Validator, inspiração para a JSR 303, isto pode ser uma tarefa simples.
Introdução
Validação de dados é uma tarefa comum, muitas vezes implementada em diferentes camadas, de diversas maneiras e até mesmo separado do framework de validação, consumindo tempo e causando erros difíceis de serem encontrados pela falta de centralização dos interesses (concerns).
Vários projetos vêm implementando e apresentando suas idéias no que diz respeito à validação de dados, entre eles: Struts, Spring e Hibernate. Neste artigo falaremos sobre a forma proposta pelo Hibernate 3, que é uma das inspirações para a JSR 303, uma das novas especificações prevista para o Java 7.
Nas primeiras versões do Hibernate 3, a API de validação estava junto do sub-projeto Hibernate Annotations, mas no momento da escrita deste artigo esta API encontra-se separada e leva o nome Hibernate Validator. Vale ressaltar que para a validação dos recursos aqui apresentados, utilizamos as próprias classes de teste do Hibernate Validator com algumas pequenas modificações e também os softwares e APIs nas seguintes versões:
· Hibernate Validator 3.0.0.GA;
· Hibernate Core 3.2.4.GA;
· Hibernate-Annotations 3.3.0.GA
· Eclipse 3.2.2;
· Java 1.6.0_01-b06.
Hibernate Validator
Seguindo o princípio da filosofia DRY (Don’t Repeat YourSelf), o Hibernate Validator trás uma forma de adicionar regras para validação automática de dados, de maneira que estas validações sejam implementadas uma e somente uma vez em toda a aplicação, eliminando a duplicação destas regras entre as diversas camadas (presentation, data access, database schema).
Utilizar annotations para adicionar regras é bastante conveniente e elegante, com elas podemos definir várias regras diretamente no modelo de classes persistente. O Hibernate Validator (H.V.) possuí algumas validações comuns (@NotNull, @Email, @Max, @Length, entre outras), mas não prende o desenvolvedor, possibilitando, a criação de validações personalizadas e internacionalizadas.
Cada annotation é associada a uma implementação de validação, que verifica se a instancia da entidade obedece a sua regra. O Hibernate faz isto automaticamente antes de um insert ou update, mas você também pode chamar a validação a qualquer momento em sua aplicação e de qualquer Java Persistence provider (JPA).
As validações podem ser utilizadas em dois níveis: aplicação e banco de dados. A primeira traz a possibilidade de validar a instancia de classes através de suas regras em tempo de execução (veja o quadro de constraints), enquanto que a segunda é incorporada ao Hibernate metamodel e ao database schema gerado, traduzindo as regras que você adicionou no mapeamento de suas entidades. Por exemplo, se você adicionar @NotNull a uma propriedade de sua entidade, a coluna irá ser declarada como not null no DDL schema gerado pelo Hibernate (hbm2ddl). Caso você não queria mais este comportamento, basta atribuir false a hibernate.validator.apply_to_ddl.
Este artigo está focado na primeira forma de validação.
Constraints
Aqui você pode ver uma lista de algumas regras que podem ser adicionadas a suas entidades, de maneira que o hibernate possa validar as informações armazenadas dentro delas. Lembre-se de que estas são constraints que o Hibernate Validator fornece para nós trabalharmos, mas podemos definir as nossas constraints personalizadas. Mas o que são constraints?Em poucas palavras: Constraints são regras de restrição, e sua semântica é definida pelas annotations que a descrevem.
Annotation Funcionalidade
@Length(min=, max=): Verifica se o tamanho da string esta dentro dos limites.
@Max(value=): Verifica se o valor é maior ou igual. Aplicado a representações de números, armazenados até mesmo em String.
@Min(value=): Verifica se o valor é menor ou igual. Aplicado a representações de números, armazenados até mesmo em String.
@NotNull: Checa se o valor não é null.
@NotEmpty: Checa se não é null e não vazia.
@Past: Checa se uma data esta no passado.
@Future: Checa se uma data esta no futuro.
@Pattern(regex=”regexp”, flag=)ou@Patten({@Pattern(...)}): Checa se a propriedade obedece à expressão regular.
@Range(min=, max=): Confere se o valor está entre o mínimo e o máximo (incluindo), aplicado a valores numéricos, mesmo armazenados em String.
@Size(min=, max=): Confere se a quantidade de elementos esta entre o mínimo e o máximo (incluído), aplicado a Array, Collection, Map.
@AssertFalse: Confere se o valor de uma propriedade boolean é false.
@AssertTrue :Confere se o valor de uma propriedade boolean é true
@Valid: Impõe uma validação recursiva aos objetos associados. Se o objeto é uma Collection, Map ou um Array, os elementos são validados recursivamente.
@Email: Confere se a string é um e-mail válido.
@CreditCardNumber: Confere se a string é um número de cartão de crédito válido.
@Digits: Verifica quantidade de dígitos ante e depois do separador de casa decimal (integerDigits e factionalDigits).
@EAN: Verifica se a string é um código EAN ou UPC-A válido
Como utilizar o framework?
É chegada a hora de “sujarmos as mãos” e ver como a teoria se aplica na prática. Lembre-se de que se você estiver utilizando o Hibernate como uma solução para o Mapeamento Objeto Relacional (ORM), a integração do Hibernate Core com o Hibernate Validador é transparente. As validações ocorrem sempre antes de qualquer insert ou update, caso haja algum erro será disparado uma exceção com as regras violadas. Se por algum motivo for necessário desabilitar a esta integração basta atribuir false a hibernate.validator.autoregister_listeners.
Para começar vamos criar uma classe que servirá apenas para nos mostrar os erros de uma forma mais amigável. Chamaremos esta classe de HandlerTest e seu propósito de existência é o de imprimir na saída padrão as mensagens de erro, se tiver alguma, caso contrário deverá nos avisar de que não há nenhum erro, veja a listagem 1.
Analisando o código, vemos que a classe HandlerTest verifica se o array de InvalidValue é igual a 0, esta é a forma da qual você pode ter certeza de que não nenhum erro foi detectado pelo Hibernate Validator, pois, sempre que for detectado um erro, haverá algum elemento no array retornado pelo validador. Caso o array invalidValues tenha algum elemento o código da listagem 1 chama o método print() para nos mostrar o quê tem dentro do array. Veja o quadro InvalidValue para saber a utilidade dos principais métodos desta classe.
Listagem 1: Classe HandlerTest
public class HandlerTest {
public static void printErrors(InvalidValue[] invalidValues) {
System.out.println("** Listagem de erros **");
if (invalidValues.length == 0) {
System.out.println("Oba! Não há erros!\n");
} else {
print(invalidValues);
}
}
private static void print(InvalidValue[] invalidValues) {
Class clazz = invalidValues[0].getBeanClass();
System.out.print("Há " + invalidValues.length);
System.out.println(" erro(s) na entidade: " + clazz.getSimpleName());
for (InvalidValue iv : invalidValues) {
System.out.print("A propriedade ");
System.out.print(iv.getPropertyName());
System.out.println(" possui o seguinte erro: ");
System.out.println(iv.getMessage());
if (iv.getValue() != null) {
System.out.print("Valor errado: ");
System.out.println(iv.getValue());
}
}
}
}
InvalidValue
GetBeanClass(): Retorna o tipo da classe que provocou o erro.
getBean(): Retorna a instancia da classe que falhou na validação.
getMessage(): Retorna a mensagem de erro, que pode estar internacionalizada.
getValue(): Retorna o valor errado.
Como já dissemos, você pode validar as informações contidas em suas entidades, em qualquer lugar do sistema. A maneira de fazer isto é chamando o método getInvalidValues da classe ClassValidator, se houver algum erro na entidade ele retornará um array de InvalidValue contendo diversas informações pertinentes a este erro. Simples, não?
Agora que já temos uma maneira simples de verificar as validações, vamos a um caso de uso fictício, suponha que para a compra de um carro o mesmo deve obedecer a dois critérios, seu IPVA deve estar pago e livre de amassados. Definimos classe Car utilizando as Annotations @AssertTrue e @AssertFalse de maneira que a propriedade ipvaPago seja igual a true, e que a propriedade amassado seja igual a false, veja a listagem 2.
Listagem 2: Classe Carro
public class Carro{
String cor;
@AssertTrue
boolean ipvaPago;
@AssertFalse
boolean amassado;
}
Na listagem 2 podemos observar que as constraints foram adicionadas em cima da propriedade, uma alternativa caso seja necessário é definidas sobre o método get da respectiva propriedade. Particularmente não gostamos de definir as regras em cima dos métodos getXX(), pois torna o código menos intuitivo e menos legível, aconselhamos que sempre utilize a propriedade para adicionar as constraints.
Acompanhe na listagem 3, que a classe AssertTest imprimirá primeiramente dois erros, mas posteriormente, como não será detectado nenhum erro pelo validador, apenas haverá uma mensagem confirmando que as informações contidas na entidade são válidas. Como não definimos nada no código referente a língua, as mensagens de erros virão na língua configurada no Sistema Operacional. Até o momento da escrita deste artigo, eram onze as línguas suportadas, entre elas: português do Brasil; inglês; espanhol; italiano; francês; chinês e alemão.
Lista 3: Classe AssertTest
public class AssertTest {
public static void main(String[] args) {
Car fuscao = new Car();
fuscao.cor = "preto";
fuscao.ipvaPago = false;
fuscao.amassado = true;
ClassValidatorclassValidator = new ClassValidator (Car.class);
InvalidValue[] invalidValues = classValidator.getInvalidValues(fuscao);
printErrors(invalidValues);
fuscao.ipvaPago = true;
fuscao.amassado = false;
invalidValues = classValidator.getInvalidValues(fuscao);
printErrors(invalidValues);
}
}
Definindo suas próprias validações
Criar nossas próprias validações é muito simples, é necessário apenas duas coisas, criar uma Annotation que descreva a regra e criar uma classe que implemente a interface org.hibernate.validator.Validator (veja a listagem 4 e 5), feito isto é só adicionar a Annotation a sua entidade para que ela seja validada.
Listagem 4: Annotation Phone
@ValidatorClass(PhoneValidator.class)
@Target({FIELD, METHOD})
@Retention(RUNTIME)
@Documented
public @interface Phone {
String ddd() default "44";
String message() default "{validator.phone}";
}
Na listagem 4, podemos acompanhar o código de uma Annotation destinada a validação de telefones. Três pontos importantes devem ser observados nesta classe. Na primeira linha temos a anotation @ValidatorClass dizendo que é utilizado a classe PhoneValidator como a implementação que irá validar a entidade anotada com @Phone. Os dois próximos pontos importantes são as propriedades ddd e message. Ambas podem ser mudadas no momento de definir uma entidade da seguinte forma:
@Phone(ddd = “45”, message = “mensagem de erro”)
A propriedade message tem propósito especifico, que é armazenar uma string que será utilizada caso um erro proveniente desta Annotation seja detectada. No exemplo, o valor default é {validator.phone}, uma mensagem nada inteligível, mas aliado ao recurso de internacionalização ela será, pois com esta chave o mecanismos de internacionalização do Hibernate Validator tentará encontrar a mensagem apropriada, caso não encontre será utilizado a string {validador.phone} na integra.
A classe PhoneValidator mostrada na listagem 5, possuí apenas dois métodos reescritos da interface Validator. Enquanto o método initialize(Phone parameters) recupera os valores atribuídos na entidade para a annotatoin @Phone o método isValid(Object value) faz o trabalho de verificar se o conteúdo da propriedade é valido, atente para o parâmetro que isValid recebe, esta é a informação que deve ser validada. Em nosso código de exemplo para um telefone ser válido é preciso estar no formado (44)0000-0000 (DDD 44 entre parênteses, seguido de quatro números, um traço e novamente quatro números).
O Hibernate Validator utiliza a classe ResourceBundle para internacionalizar as mensagens de erros. É bastante tranqüilo trabalhar com ela, primeiramente precisamos de um arquivo .properties, dentro dos padrões (veja o quadro: Um pouco sobre internacionalização); a Annotation precisa estar preparada para trabalhar com a mensagem internacionalizada e que seja explicitado que utilizaremos o arquivo específico para as mensagems.
Na listagem 6, temos um código completo, que imprime a mesma mensagem de erro em duas línguas diferente. Para isto foram necessárias apenas algumas linhas de código adicionais, veja que foi preciso passar no segundo parâmetro do construtor de ClassValidator um ResouceBundle que foi criado apartir de um Locale.
É possível sobrescrever as mensagens padrão do H.V., a regra é simples. Dentro do arquivo que você armazena as mensagens internacionalizadas, você adiciona a chave validator.nomedaannotation. Por exemplo, para mudar a mensagem da annotation @NotNull haverá no arquivo a seguinte chave:
validator.notnull=Erro, a propriedade não pode ser null
Se for necessário informar os valores permitidos, como é caso de @Length, podemos colocar o nome da variável entre chaves, desta forma, esta será trocada automaticamente pelo valor configurado na entidade. Veja o exemplo a seguir:
validator.length=Xii!! Deu erro no Length, os valores devem estar entre {min} e {max}
Listagem 5: Classe PhoneValidator
public class PhoneValidator implements Validator{
private String dddValid;
public void initialize(Phone parameters) {
dddValid = parameters.ddd();
}
public boolean isValid(Object value) {
if (value == null) {
return true;
}
String phone = (String) value;
//(44)9962-3019
String reg = "\\(" +dddValid+ "\\)[0-9]{4}\\-[0-9]{4}";
Pattern pattern = Pattern.compile(reg);
Matcher match = pattern.matcher(phone);
return match.matches();
}
}
Listagem 6: Classe PhoneTest
public class PhoneTest {
public static void main(String[] args) {
HomePhone hPhone = new HomePhone();
hPhone.phone = "3366-3330";
Locale ptBR = new Locale("pt", "BR");
ResourceBundle rBundleDefault = ResourceBundle.getBundle("messages", ptBR);
ResourceBundle rBundleEnglish = ResourceBundle.getBundle("messages", Locale.ENGLISH);
ClassValidatorclassValidator;
classValidator = new ClassValidator(HomePhone.class, rBundleEnglish);
InvalidValue[] invalidValues = classValidator.getInvalidValues(hPhone);
printErrors(invalidValues);
classValidator = new ClassValidator(HomePhone.class, rBundleDefault);
invalidValues = classValidator.getInvalidValues(hPhone);
printErrors(invalidValues);
hPhone.phone = "(44)9962-3019";
invalidValues = classValidator.getInvalidValues(hPhone);
printErrors(invalidValues);
}
}
Não se preocupe
O Hibernate Validator cuida de vários problemas comuns do desenvolvimento de software. Referencia circular, muito discutido no quesito qualidade de software, é um destes problemas, este tipo de situação, comum, levou a alguns brasileiros criarem um pluguin para o Eclipse chamado ByeCycle que auxilia a eliminar referencias circulares. Acompanhe pela listagem 7 que a entidade Contact nos diz que a entidade Brother também deve passar pela validação (@Valid), mas a Classe Brother faz o mesmo para com a classe Contact, isto poderia facilmente levar a um problema sério de referencia circular, mas isto não é algo do qual devemos nos preocupar, pois o H. V. sabe lidar com esta situação perfeitamente, nos permitindo usar estas classes.
Listagem 7: Referencia circular
public class Contact {
@NotNull
public String phone;
@Valid
public Brother brother;
}
public class Brother {
@NotEmpty
public String name;
@Valid
public Contact contact;
}
É possível validar todos os elementos de uma Collection ou array facilmente, não é necessário nenhum recurso “informágico”. Basta adicionar a Annotation @Valid a estrutura que esta terá todos os seu itens validados. Acompanhe a listagem 8 que demonstra como uma classe TV pode ter o seu Map de Show verificado item a item pelo Hibernate Validator.
Listagem 8: iterable
public class Tv {
@NotNull
public String name;
@Valid
public Mapshows = new HashMap ();
}
public class Show {
@NotNull
public String name;
}
Esta poderosa ferramenta nos permite também agregar várias expressões regulares, para validar uma única propriedade, acompanhe a listagem 9, observe que definimos duas E.R. e também personalizamos as mensagens que serão utilizadas para informar o usuário caso alguma destas regras sejam desrespeitadas.
Listagem 9: agregando E.R.
@Patterns( {
@Pattern(regex = "^[A-Z0-9-]+$", message = "must contain alphabetical characters only"),
@Pattern(regex = "^....-....-....$", message = "must match ....-....-....") }
)
Integração com Hibernate
A utilização do Hibernate (core) propriamente dito em conjunto com o Hibernate Validator é feita através do Hibernate Annotation (ou Hibernate EntityManager) e neste caso a validação será automática, não será necessário nenhum código para chamar o validador, pois esta chamada ocorrerá antes de qualquer inserção de dados novos ou alterações (save ou update).
Para verificar este comportamento foi criado uma entidade chamada Linha, a ela demos alguns atributos e algumas regras para serem verificadas, como por exemplo @NotNull e @Length(max = 100). Também foram criadas as classes HibernateUtil e LinhaTeste, classes utilizadas para nos fornecer a Session e testar o comportamento de validação respectivamente.
Após a execução do teste dois tipos de exceções foram lançadas: org.hibernate.PropertyValueException e org.hibernate.validator.InvalidStateException ambas indicando problemas encontrados pelo Hibernate Validator, veja a listagem 11 e 12 para verificar um pequeno trecho da exceção.
Não é recomendável mas caso seja necessário, é possível desligar a pré validação atribuindo false a variável de configuração:
hibernate.validator.autoregister_listeners
Listagem 10: Classe LinhaTeste
public static void main(String[] args) {
Linha linha = new Linha();
linha.setIdLinha(new BigDecimal(10));
Session session = HibernateUtil.getSession();
session.getTransaction().begin();
session.save(linha);
session.getTransaction().commit();
HibernateUtil.getSession().close();
}
Listagem 11: exceção lançada pela validação do Hibernate
Exception in thread "main" org.hibernate.PropertyValueException: not-null property references a null or transient value: org.hibernate.validator.test.hibernateIntegracao.Linha.codigo
...
Listagem 12: exceção lançada pela validação do Hibernate
Exception in thread "main" org.hibernate.validator.InvalidStateException: validation failed for: org.hibernate.validator.test.hibernateIntegracao.Linha
...
Camada de apresentação
JBoss Seam é um poderoso framework para a construção de aplicações Web 2.0, unificando e integrando tecnologias como: AJAX, JSF, EJB3, Java Portlets e BPM. Este projeto é desenhado para eliminar a complexidade destas arquiteturas, de maneira a possibilitar os desenvolvedores criar aplicações web simplesmente anotando classes POJOs [7].
JavaServer Faces é um framework MVC, também para desenvolvimento de aplicações Web, que permite o desenvolvimento de aplicações para internet ao estilo Delphi, (arrastando e soltando). Considerado por muitos, a última palavra em desenvolvimento Web, resultado obtido pela maturidade de tecnologias como JSP/Servlet (Model1), Model2 (MVC) e Struts.
Trabalhando juntas, as tecnologias JSF e JBoss SeamÔ pode-se disparar o processo de validação até a camada de apresentação usando as tags
Listagem 13: visualizando as mensagens de erro com JSF
< s:validateAll>
< div>
Telefone:
< h:inputText value="#{validator.phone}" required="true" />
< /div>
< /s:validateAll>
JSR 303: Bean Validation
Bean Validation, já aprovada e prevista para a versão 7 do Java, deverá padronizar a definição de validadores, regras de validação e afins. Baseado em annotations e descritores XML, este novo recurso fornecerá em tempo de execução meios de checar e validar as propriedades de classes persistentes. Para validações mais comuns e simples, serão utilizadas annotations, enquanto casos mais complexos ou regras de negócios específicas utilizarão um descritor XML para configurar a validação [1].
Fortemente inspirada no Commons-Validator, Hibernate Validator e XWork Validation Framework, a JSR 303 poderá ser utilizada não somente em aplicações web, mas também em aplicações desktop e para a camada de persistência, permitirá o envio mensagens de erros internacionalizadas, e também a personalização através da classe ResourceBundle.
O líder deste sub-projeto (Hibernate Validator) é um dos membros da JSR 303, por isto podemos esperar que esta nova especificação do Java seja bem semelhante ao que descrevemos neste artigo.
Considerações Finais
Consistência de dados, testes e validação, são itens dos quais todos precisamos, mais cedo ou mais tarde a esta necessidade “bate nossa porta”, é nesta hora que precisamos tomar a decisão de qual tecnologia e estratégia adotar. O Hibernate Validator fornece um tratamento bem interessante, como ela é fortemente ligada a Bean Validation, acreditamos que vale, e muito, dedicar algumas horas para a pesquisa e aprendizado deste recurso, não somente porque é algo que está por vir no Java 7, mas porque este tende a ser um padrão no desenvolvimento de aplicações.
Para facilitar a vida do leitor, está disponível para download um projeto eclipse com os fontes utilizados para validar as informações contidas neste material. Nele você encontrara exemplos de validações, incluindo até mesmo algumas que não foram extensivamente exploradas neste texto. É importante ressaltar que muitos dos códigos foram retirados ou modificados dos próprios testes unitários (JUnit) do Hibernate Validator, por isto, caso o leitor queira ter acesso aos originais basta buscar direto na fonte.
Referências
[1] JSR 303: Bean Validation http://jcp.org/en/jsr/detail?id=303
[2] Hibernate - http://www.hibernate.org
[3] Commons-Validator - http://jakarta.apache.org/commons/validator
[4] XWork Validation Framework - http://wiki.opensymphony.com/display/XW/Validation+Framework
[5] API da classe ResourceBundle
[6] Internacionalization support - http://java.sun.com/javase/6/docs/technotes/guides/intl/index.html
[7] http://www.jboss.com/products/seam
Oque é ser programador?
Ser um programador nada mais é doque um transformador, assim como uma planta faz fotosintece(como escreve isso?) transformando agua e luz solar em seu próprio alimento, o orogramador transforma café em linhas de código
Continuous Integration
i believe that is a important paradigm....
An important part of any software development process is getting reliable builds of the software. Despite its importance, we are often surprised when this isn't done. We stress a fully automated and reproducible build, including testing, that runs many times a day. This allows each developer to integrate daily thus reducing integration problems.
http://www.martinfowler.com/articles/continuousIntegration.html
An important part of any software development process is getting reliable builds of the software. Despite its importance, we are often surprised when this isn't done. We stress a fully automated and reproducible build, including testing, that runs many times a day. This allows each developer to integrate daily thus reducing integration problems.
http://www.martinfowler.com/articles/continuousIntegration.html
Coleção de exemplos e templates reutilizaveis com JEE 5
Now i'll indicate to you a p4j5 project, this project is a collection of samples and reusable templates which demonstrates patterns, approaches and architectural ideas for the Java EE 5 platform.
https://p4j5.dev.java.net/
http://www.adam-bien.com/tdb
https://p4j5.dev.java.net/
http://www.adam-bien.com/tdb
SOA x ESB, oque?
Original: http://www.guj.com.br/posts/list/77933.java
Encontrei no forum uma explicação bastante clara sobre o assunto, leiam...
Pois bem. Primeira coisa que deve ser entendida sobre SOA (Arquitetura Orientada a Serviços) é que SOA não é um produto, ela é simplesmente um paradigma. Do mesmo jeito que programação orientada a objetos é um paradigma, e não um produto. Dito isso, outro ponto importante a ser levado em consideração é que SOA está na moda. Por isso você verá muitas empresas por aí (IBM, Oracle, BEA e outras) vendendo SOA, empurrando SOA para os seus clientes goela abaixo. Isso é uma enganação. SOA não é um produto e portanto não pode ser vendida. SOA é algo que você terá que implementar na prática, por si só, ou junto com a sua equipe de desenvolvimento. O que essas empresas podem lhe fornecer será no máximo algumas ferramentas, frameworks, bibliotecas para facilitar o seu trabalho.
Outro ponto importantíssimo é entender se você realmente precisa de SOA, ou seja, quando é que SOA se torna necessária de fato?
SOA é um paradigma para grandes sistemas distribuídos de proprietários e tecnologias diferentes! Se este não for o seu caso, você não precisa de SOA!
Voltando agora para a sua pergunta e levando em consideração as afirmações acima:
O que é um ESB (Enterprise Service Bus)?
Nada melhor para explicar um conceito "novo" do que através de um exemplo. Suponha a seguinte situação. Uma empresa X possui um sistema de grande porte desenvolvido em Java (JEE, EJB e outros). Essa empresa X adquire uma empresa Y que por sua vez utiliza tecnologia .NET. A empresa possui um sistema de CRM que necessita, por alguma motivo, obter informações dos dois sistemas para que possa fazer algum processo de atendimento ao cliente. Para fazer isso você teria várias opções, poderia conectar os dois sistemas diretamente, poderia desenvolver uma classe (ou todo um pacote de classes) que faça acesso aos dois sistemas.
Com tempo, à medida que surgissem outras necessidades de conectar esses dois sistemas, você acabaria por ter uma confusão geral de sistemas acessando outros sistemas. Um caos de verdade. Para evitar isso, entra o papel de ESB, que neste caso seria um "negociador", seria uma "interface" para a qual você iria solicitar a execução de alguns processos, consultas, etc. Ou seja, um elemento intermediário que seria responsável por conectar sistemas diferentes. O seu sistema Java nem tomaria conhecimento de que o outro sistema é feito em .NET ou em qualquer outra tecnologia, porque ele se comunicaria apenas com o ESB, o qual por sua vez teria o papel de se conectar a esses outros sistemas. Resumidamente, ESB seria uma abstração dessa interconexão de sistemas que usam tecnologias diferentes.
A maneira mais comum de se implementar um ESB hoje é através de Web Services, mas isso não é regra, existem outras formas de se realizar a mesma atividade. (ESB <> Web Services).
Se ainda não está claro o que é um ESB, vamos tentar entrar mais na parte prática da coisa, vamos imaginar o que poderia ser um ESB. Ele poderia muito bem ser um sistema "independente" desenvolvido em .NET que disponibiliza uma séria de Web Services e que se conecta a vários backends usados pela empresa. (Usei exemplo de .NET em um fórum Java de propósito, para destacar que SOA é independente de tecnologia usada). Como Web Sevices são um padrão (tudo bem que esse padrão ainda possui diversas coisas "não padronizadas", mas é possível seguindo boas práticas e alguns padrões já estabelecidos alcançar um resultado bom), o seu sistema Java poderia se conectar a esse "ESB.NET" atráves de Web Services e obter o resultado desejado.
Só para concluir e para ficar bem claro:
SOA é um paradigma e não um produto.
Se alguém chegar dizendo que tem uma solução SOA pronta para sua empresa, isso é mentira.
ESB é o coração de uma arquitetura SOA, é o ponto de interconexão entre sistemas que usam tecnologias diferentes.
SOA está na moda, cuidado ao adquirir "produtos prontos".
Web Services são apenas uma maneira dentre outras para implementar tal arquitetura (embora de longe a mais usada).
Espero ter esclarecido para você e para outros leitores deste fórum alguns conceitos de SOA.
Encontrei no forum uma explicação bastante clara sobre o assunto, leiam...
Pois bem. Primeira coisa que deve ser entendida sobre SOA (Arquitetura Orientada a Serviços) é que SOA não é um produto, ela é simplesmente um paradigma. Do mesmo jeito que programação orientada a objetos é um paradigma, e não um produto. Dito isso, outro ponto importante a ser levado em consideração é que SOA está na moda. Por isso você verá muitas empresas por aí (IBM, Oracle, BEA e outras) vendendo SOA, empurrando SOA para os seus clientes goela abaixo. Isso é uma enganação. SOA não é um produto e portanto não pode ser vendida. SOA é algo que você terá que implementar na prática, por si só, ou junto com a sua equipe de desenvolvimento. O que essas empresas podem lhe fornecer será no máximo algumas ferramentas, frameworks, bibliotecas para facilitar o seu trabalho.
Outro ponto importantíssimo é entender se você realmente precisa de SOA, ou seja, quando é que SOA se torna necessária de fato?
SOA é um paradigma para grandes sistemas distribuídos de proprietários e tecnologias diferentes! Se este não for o seu caso, você não precisa de SOA!
Voltando agora para a sua pergunta e levando em consideração as afirmações acima:
O que é um ESB (Enterprise Service Bus)?
Nada melhor para explicar um conceito "novo" do que através de um exemplo. Suponha a seguinte situação. Uma empresa X possui um sistema de grande porte desenvolvido em Java (JEE, EJB e outros). Essa empresa X adquire uma empresa Y que por sua vez utiliza tecnologia .NET. A empresa possui um sistema de CRM que necessita, por alguma motivo, obter informações dos dois sistemas para que possa fazer algum processo de atendimento ao cliente. Para fazer isso você teria várias opções, poderia conectar os dois sistemas diretamente, poderia desenvolver uma classe (ou todo um pacote de classes) que faça acesso aos dois sistemas.
Com tempo, à medida que surgissem outras necessidades de conectar esses dois sistemas, você acabaria por ter uma confusão geral de sistemas acessando outros sistemas. Um caos de verdade. Para evitar isso, entra o papel de ESB, que neste caso seria um "negociador", seria uma "interface" para a qual você iria solicitar a execução de alguns processos, consultas, etc. Ou seja, um elemento intermediário que seria responsável por conectar sistemas diferentes. O seu sistema Java nem tomaria conhecimento de que o outro sistema é feito em .NET ou em qualquer outra tecnologia, porque ele se comunicaria apenas com o ESB, o qual por sua vez teria o papel de se conectar a esses outros sistemas. Resumidamente, ESB seria uma abstração dessa interconexão de sistemas que usam tecnologias diferentes.
A maneira mais comum de se implementar um ESB hoje é através de Web Services, mas isso não é regra, existem outras formas de se realizar a mesma atividade. (ESB <> Web Services).
Se ainda não está claro o que é um ESB, vamos tentar entrar mais na parte prática da coisa, vamos imaginar o que poderia ser um ESB. Ele poderia muito bem ser um sistema "independente" desenvolvido em .NET que disponibiliza uma séria de Web Services e que se conecta a vários backends usados pela empresa. (Usei exemplo de .NET em um fórum Java de propósito, para destacar que SOA é independente de tecnologia usada). Como Web Sevices são um padrão (tudo bem que esse padrão ainda possui diversas coisas "não padronizadas", mas é possível seguindo boas práticas e alguns padrões já estabelecidos alcançar um resultado bom), o seu sistema Java poderia se conectar a esse "ESB.NET" atráves de Web Services e obter o resultado desejado.
Só para concluir e para ficar bem claro:
SOA é um paradigma e não um produto.
Se alguém chegar dizendo que tem uma solução SOA pronta para sua empresa, isso é mentira.
ESB é o coração de uma arquitetura SOA, é o ponto de interconexão entre sistemas que usam tecnologias diferentes.
SOA está na moda, cuidado ao adquirir "produtos prontos".
Web Services são apenas uma maneira dentre outras para implementar tal arquitetura (embora de longe a mais usada).
Espero ter esclarecido para você e para outros leitores deste fórum alguns conceitos de SOA.
Assinar:
Postagens (Atom)