quinta-feira, 1 de agosto de 2019

Como exibir mensagens de erros específicas para Constraints no Java

      Nesse post vou mostrar uma forma de pergar um erro mais específico a partir de uma Exception (nesse caso uma PersistenceException mas poderia ser qualquer outra). Estou assumindo que estamos em uma aplicação JSF e tentamos persistir uma informação que já existe no banco de dados e acaba violando uma constraint, então queremos exibir uma mensagem mais precisa ao usuário. Podemos fazer da seguinte forma:

... //declaração da classe e outras propriedades e métodos
 
private static final String MENSAGEM_PADRAO = "Não conseguimos consultar as informações, favor informar a área de negócio responsável.";

...

try{
    ...  //seu código
 
}catch ...{ //outros blocos catch

}catch (final PersistenceException e) {
            Exception cause = e;
            Integer count = 0;
            while (cause != null && cause.getMessage() != null
                    && cause.getMessage().contains("NOME_CONSTRAINT_BANCO")
                    || count == 10)
            {
                if ( cause != null )
                {
                    cause = (Exception) cause.getCause();
                }
                count += 1;
            }
            String mensagem = null;
            if ( cause != null && cause.getMessage() != null
                    && cause.getMessage().contains("NOME_CONSTRAINT_BANCO") )
            {
                mensagem = gerarMensagem("Sua mensagem");
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(
                FacesMessage.SEVERITY_ERROR, mensagem, null));

            }
            mensagem = gerarMensagem(
                            MENSAGEM_PADRAO);
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(
                FacesMessage.SEVERITY_ERROR, mensagem, null));
        }
}catch (final Exception e)
{
    ...
}


sábado, 27 de julho de 2019

Resolvendo problema CORS no Angular

Olá, hoje vou falar sobre o CORS – Cross-Origin Resource Sharing que significa compartilhamento de recursos de origem cruzada.

Antes era muito comum o uso de iFrames ou similares para fazer com que um site acessasse diretamente conteúdo de outros o que também era válido para aplicações web mais complexas, o problema é que isso começou a ser explorado por pessoas mal intencionadas para se passarem por um site ou serviço que não são e roubar informações ou outras atividades ilícitas. Então os navegadores começaram a “bloquear” esse tipo de coisa, validando antes se a origem tem acesso ao backend vindo de um IP diferente ou não configurado em uma digamos “White list”.

Trarar o CORS é obrigação do backend ou infra, mas é possível e também uma boa prática tratar no frontend. Para isso criamos um Proxy no nosso frontend. Como funciona um proxy? Ele recebe a requisição e a repassa com uma nova configuração de rede.

Vamos criar o nosso proxy, crie um arquivo chamado proxy.config.js no mesmo diretório em que se encontra o seu package.json  com o seguinte conteúdo:

{
"/api": {
    "target": "http://localhost:8080", //endereço do backend
    "secure": false
}
}
Agora configure dentro do seu angular.json o uso do proxy:
...
"defaults"
:{
     "serve":{
          "proxyConfig":"./proxy.config.js"
      }
...


Fonte:
Para ver todas as opções da configuração de proxy veja:
https://webpack.js.org/configuration/dev-server/#devserver-proxy

quarta-feira, 17 de julho de 2019

Método que verifica interseção entre períodos

    Neste artigo rápido trago um método que verifica se há interseção entre dois períodos de datas. Todo sistema precisa trabalhar com datas e é muito comum precisarmos desse tipo de validação:


public static boolean isIntersecaoEntrePeriodos(final Date aIni, final Date aFim, final Date bIni,
            final Date bFim)
    {
        if ( (aFim == null && bFim == null)
                || (aFim == null && aIni.compareTo(bIni) <= 0)
                || (aFim == null && bFim != null && aIni.compareTo(bFim) <= 0)
                || (bFim == null && bIni.compareTo(aIni) <= 0)
                || (bFim == null && aFim != null && bIni.compareTo(aFim) <= 0)
                || ((aFim != null && bFim != null) &&
                        ((aIni.compareTo(bIni) <= 0 && aFim.compareTo(bFim) >= 0)
                        || (aIni.compareTo(bIni) <= 0 && aFim.compareTo(bIni) >= 0)
                        || (aIni.compareTo(bIni) >= 0 && aFim.compareTo(bFim) <= 0)
                        || (aIni.compareTo(bFim) <= 0 && aFim.compareTo(bFim) >= 0))) )
        {
            return true;
        }
        return false;
    }

sábado, 25 de maio de 2019

Usando Hibernate Envers para auditoria


Pra quem não conhece o Hibernate Envers é o módulo de auditoria e versionamento de entidades. Neste post vou mostrar como configurar o envers no Spring Boot.

Primeiro precisamos adicionar a dependência do Envers no POM do nosso projeto:

<dependency>
     <groupId>org.hibernate</groupId>
     <artifactId>hibernate-envers</artifactId>
     <version>5.3.1.Final</version>
</dependency>

Precisamos também criar uma tabela padrão do Envers chamada “REVINFO” com dois campos, um ID e um campo pra guardar o timestamp das alterações:
  
CREATE TABLE revinfo (
rev integer NOT NULL,
revtstmp bigint,
CONSTRAINT revinfo_pkey PRIMARY KEY (rev)
)

Note que o campo para guardar a chave de revisão por padrão é um integer, para mudar para bigint é preciso fazer customização do Envers, criando uma entidade que contenha o campo do tipo Long como abaixo:

@Entity
@RevisionEntity
public class EntityRevisionCustom implements Serializable {
 
  @Id
  @GeneratedValue
  @RevisionNumber
  private Long rev;

  @RevisionTimestamp
  private Long timestamp;

  /* getts and setts */
}

Agora o SQL que cria a tabela passa a ser assim:

CREATE TABLE revinfo (

rev bigint NOT NULL,
revtstmp bigint,
CONSTRAINT revinfo_pkey PRIMARY KEY (rev)
)


Outra coisa que leva a criação dessa classe customizada é poder colocar mais informações nela, como por exemplo o usuário logado, que é o responsável pela alteração. Para isto é preciso criar um listener que possa pegar esse usuário e settar na entidade de forma transparente para o desenvolvedor.

Isso requer que informemos o Listener na classe customizada:

@Entity
@RevisionEntity(MyRevisionListener.class)
public class EntityRevisionCustom implements Serializable {
...
}

          Segue o exemplo de um listener que pega o usuário da sessão e preenche na classe customizada:

public class MyRevisionListener implements RevisionListener {
    @Override
    public void newRevision(Object revisionEntity) {
        EnversCustomRevision rev = (EnversCustomRevision) revisionEntity;
        rev.setUsuCodUsuario(SessionBean.getCodUsuarioLogado());
    }
}

Depois de adicionar a dependência e criar a tabela revinfo (fazendo as customizações ou não), podemos usar o Envers na nossa aplicação. Basta anotar cada Entidade que for auditada com a anotação @Audited do pacote org.hibernate.envers e criar uma tabela de mesmo nome da tabela original adicionando o sufixo “_AUD” (ou “_aud”) dependento do seu padrão, acrescentando dois campos: rev (do tipo integer se não tiver customizado) e revtype (do tipo smalint).

@Entity
@Table(name = "USU_USUARIO")
@Audited
public class Usuario implements Serializable {
...
}

Caso a tabela criada para auditoria seja diferente do nome da tabela da entidade + o sufixo “_AUD”, deve ser informado na classe colocando a anotação @AuditTable, que recebe a propriedade value para informar o nome da tabela a ser usada.   

@AuditTable(value = "USU_AUD")

Pronto, assim o sistema já está sendo auditado.

segunda-feira, 22 de abril de 2019

Configurando o computador para desenvolver projetos Java Web (JavaEE)


Este artigo é um guia rápido das ferramentas a serem instaladas para deixar a máquina pronta para trabalhar com projetos JavaEE, te levando aos links que te ajudarão a instalar o JDK, o Git, o Maven, o Wildfly, o Eclipse e dentro do eclipse o JBoss Tools.

Para configurar o JDK 8 em qualquer plataforma, acesse:


Para configurar o Maven, acesse:


Para instalar o Git, acesse:


Para baixar o Eclipse para JavaEE basta pesquisar exatamente por esse termo no Google e abrir o primeiro link, então procurar a versão Enterprise Java Developers e baixar segundo a sua plataforma, segue link da ultima versão até a data desse artigo:


Agora vamos instalar o Wildfly, que é o servidor de aplicações, esse primeiro link é para download:


Este segundo é o guia para desenvolvedores, caso nunca tenha trabalhado com o wildfly:


Esta última parte é para usarmos o wildfly dentro do eclipse para facilitar o desenvolvimento. Dentro do eclipse, abra o menu Marketplace que geralmente fica dentro do menu help, e procure por JBoss Tools, instale a última versão disponível:
  


Para banco de dados uso o PostgreSQL, que é um banco grátis e super poderoso:
         
          https://www.enterprisedb.com/downloads/postgres-postgresql-downloads

Agora temos todas as ferramentas para trabalhar com JavaEE.




sexta-feira, 22 de março de 2019

Pegando o RealPath em uma aplicação JEE


As vezes precisamos do RealPath da nossa aplicação para lermos e/ou escrevermos arquivos através do Java, e em aplicações JavaEE uma boa forma de fazermos isso é através de um ServletContextListener, uma vez que este listener escuta quando sua aplicação inicializa ou finaliza no container web ou servidor de aplicação.

Usando o ServletContextListener ao invés do FacesContext para pegar o RealPath não ficamos presos ao JSF por exemplo, ou outra tecnologia, e podemos usar o RealPath em processos e situações diversas.

Geralmente tenho uma classe em um pacore br.com.meudominio.utils chamada Constants onde guardo algumas constantes e variáveis estáticas com algumas configurações do sistema (embora prefira usar um cadastro de Parâmetros Gerais do Sistema para a maioria das configurações), e ao pegar o RealPath é nessa classe que seto essa configuração. Veja o código do listener abaixo:

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebFilter;

import br.com.meudominio.Constants;

@WebListener
public class RealPath implements ServletContextListener{

    @Override
    public void contextDestroyed( ServletContextEvent sce ) {
        Constants.REAL_PATH = sce.getServletContext().getRealPath( "/" );
       
    }

    @Override
    public void contextInitialized( ServletContextEvent sce ) {
        // TODO Auto-generated method stub
       
    }

}

Na classe Constants tenho algo como:

public final class Constants
{
      ...

public static String REAL_PATH = "";

     ...
}

Pronto, em qualquer lugar do sistema basta usar Constants.REAL_PATH para pegar o RealPath da minha aplicação.

terça-feira, 19 de março de 2019

Criando uma biblioteca de componentes com Angular 7, utilizando em projetos externos e publicando no NPM


Frameworks JavaScript estão sempre mudando, e geralmente são mudanças complexas que nos obrigam a reaprender como fazemos as coisas. Não foi diferente com a questão da criação de bibliotecas do Angular, que até a versão 5 era apenas um projeto comum, o qual empacotávamos no formato NPM e publicávamos. Agora, a partir da versão 7 em diante o Angular cria uma espécie de workspace, onde é possível criar vários projetos e bibliotecas, e são essas bibliotecas internas que podemos exportar e podemos usar em outros projetos, e até publicar no NPM.

Com isso, muita coisa mudou, porque essa biblioteca interna, (pelo menos por enquanto, até a versão 7.1.2 do Angular), não contém os arquivos environments.prod.ts e environments.ts para tratarmos a diferença entre algumas configurações de produção e o ambiente de desenvolvimento, também não existe a estrutura da pasta assets para colocarmos nossas imagens e o Angular conseguir encontrá-las de forma fácil.

Essas dificuldades eu contornei da seguinte forma: as imagens eu coloco em texto base64 direto na tag <img> e quando preciso pegar uma URL em uma biblioteca uso JavaScript para obter a URL de forma dinâmica: (window.location.protocol + window.location.hostname;).

Outra mudança que houve foi o arquivo angular-cli.json que teve seu nome alterado para angular.json e sua estrutura mudou um pouco, passando a conter múltiplos projetos (como o de testes e as bibliotecas) pois como disse, o que criamos com “ng new” a partir da versão 7 do Angular se comporta como um workspace.

Agora que já falamos das mudanças e alguns contratempos que tive com elas, vamos a criação do projeto. Abrindo no terminal a pasta do seu workspace, digite:

$        ng new teste --create-application=false

          Quando indagado sobre a criação do Router e do CSS escolha as opções padrão.

A opção --create-aplication usada acima também é nova, e faz com que o Angular não crie o projeto inicial, bem com a pasta src, criando apenas o Workspace Angular por assim dizer. Basicamente isso é útil para criarmos bibliotecas, pois gera um workspace de mesmo nome da biblioteca. Note que o Angular aceita tanto comandos com camelCase quanto separados por ífem (-), então poderia ser --createApplication=false.

          Aproveite e dê uma olhada nos arquivos package.json que continua com as dependências do projeto  e angular.json, que está praticamente vazio aguardando a criação de um projeto ou biblioteca.

          Vamos criar a biblioteca, posicione o terminal na nova pasta criada (teste):

$        cd ..

E crie a biblioteca com o seguinte comando:

$        ng g library teste --prefix=lib

          Na linha acima, foi criada a biblioteca “teste” e ao invés de usarmos o prefixo “app” como de costume, dissemos para o Angular usar o prefixo “lib”. Fique à vontade para escolher o prefixo que desejar, isso é importante para evitar conflitos entre a biblioteca e os apps que a usam.
         
          Note que o conteúdo do arquivo angular.json mudou, temos nele a propriedade que indica a versão do projeto: “version”, a propriedade que indica o pacote raiz que contém os projetos: “newProjectRoot”, e então temos a propriedade que indica os nossos projetos: “projects”. Dentro da propriedade “projects” há uma propriedade para cada projeto que criarmos, nesse caso haverá apenas o projeto “teste”, e dentro da propriedade “teste” teremos as propriedades de configuração deste projeto específico, como o tipo do projeto, o prefixo usado, a raiz do projeto, o source do projeto e outras configurações pertinentes.

A estrutura do projeto também foi alterada, agora existe uma pasta “projects” com a pasta “teste” que é o nosso projeto dentro dela; e dentro da pasta “teste” temos o diretório “src” que conterá tudo que pertencer a lib propriamente dita, o arquivo “package.json” da lib que especificará suas dependências que serão compiladas e posteriormente instaladas junto com ela quando um cliente usar npm install e também o arquivo ng-package.json. Os demais arquivos são de menor importância. É também no arquivo “package.json” da lib que especificamos o autor, a licença, o repositório, etc.

       A lib já foi criada contendo um componente e um service dentro de src/lib . Também vemos outro arquivo importante dentro da pasta src: public_api.ts. Nesse arquivo devemos exportar todos os módulos, componentes e services que criarmos, para que possam ser usados por quem instalar nossa biblioteca.

          export * from './lib/teste.service';
export * from './lib/teste.component';
export * from './lib/teste.module';

No diretório principal, o arquivo “tsconfig.json” tem as configurações de transpilação e build do projeto. Ele recebe o path da biblioteca que criamos para podermos usar nesse projeto, enquanto que em projetos externos ela será instalada com npm install e o conteúdo ficará em node_modules.

"paths": {
      "teste": [
        "dist/teste"
      ],
      "teste/*": [
        "dist/teste/*"
      ]
}

          Vamos buildar o projeto:

$        ng build teste   

          Veja que o projeto é buildado normalmente. Mas a frente vamos ver como usá-lo em outro projeto e também como publicar no npm. Agora vamos ver como criar novos componentes para a biblioteca. Digite o comando abaixo:

$        ng g c meu-componente --project=teste

Veja que a única coisa que mudou foi que especificamos em qual projeto o componente seria gerado pelo AngularCli. O novo componente deve ser declarado no módulo da nossa biblioteca e também no arquivo de entrada, o public_api.ts.

Com isso podemos re-buildar nossa aplicação. Uma novidade desde a versão 6.2 é o re-build pode ser automático a medida que arquivos forem alterados, para isso basta acrescentar a opção --watch no momento do build, a partir de então os demais serão disparados sozinhos.

$        ng build teste --watch

Agora vamos ver como usar a biblioteca em um projeto externo e como publicar no npm.

Para isso temos que empacotar nossa biblioteca em uma arquivo .tgz, por tanto, vamos criar um script no “package.json” raiz para facilitar este trabalho. Na seção “scripts” adicione o seguinte trecho de código:

"scripts": {
    ...
    "npm_pack_teste": "cd dist/teste && npm pack"
 }

Agora podemos usar o seguinte comando para empacotar a biblioteca “teste”:

$        npm run npm_pack_teste

Isto criou o arquivo “teste-0.0.1.tgz” dentro de “dist/teste” com a versão especificada no arquivo “package.json” da lib como já dito anteriormente. Podemos inclusive criar um script que faz o build e o empacotamento de uma só vez:

"scripts": {
    ...
    "npm_pack_teste": "cd dist/teste && npm pack",
    "package_teste": "ng build teste && npm run npm_pack_teste "
 }

E agora basta executar:

$        npm run package_teste

Pronto, temos nossa biblioteca buildada e empacotada para usarmos onde quisermos! Para usarmos em projetos próprios não precisamos publicar no npm. Isso é bom para empresas que não querem expor suas bibliotecas, pode-se criar um repositório interno para elas e quando for usar o npm install basta passar o caminho completo de onde a biblioteca está.

Uma vez instalada a biblioteca, o uso é normal como qualquer pacote npm instalado na aplicação.

Agora vamos a publicação no npm. Antes de criar uma biblioteca, se é sua intenção publicá-la no npm é bom checar se o nome que pretende dar a sua biblioteca já não existe lá, para evitar ter que mudar depois de criado todo o projeto.

O arquivo “package.json” deve estar com as informações de nome, versão, autor, licença, repositório, palavras chaves e outras além das dependências, scripts, etc... como abaixo:

...
"name": "teste",
"version": "1.0.0",
"license": "MIT",
"author": {
    "name": "seu_nome",
    "email": "seu_email",
    "url": "seu_site_ou_blog"
 },
 "bugs": {
 "url":"url_issues_git"
  },
 "homepage":"url_git",
 "keywords": [
    "angular",
    "angular2",
    "angular4",
    "p-calendar",
    "p-calendar-ptbr",
    "primeNG",
    "datepicker",
    "calendar",
    "pt-BR"
 ],
 "repository": {
    "type": "git",
    "url": "git+https://endereço_rep_git"
 },
...

O npm usará sua página de README.md com a página inicial da sua biblioteca no servidor. Como agora estamos tratando de mais de uma biblioteca por workspace, o README.md deve ser copiado para o destino onde a biblioteca é buildada. Caso haja um arquivo LICENSE também deve ser colocado lá.

É preciso criar uma conta caso você não tenha, ou fazer login para poder compartilhar seus pacotes. A criação da conta é bem simples e eles pedem um username, password e e-mail. É necessário a confirmação do e-mail antes de publicar algo caso a conta seja nova. O comando para criar uma conta é:

$       npm adduser

Ao criar a conta ele já loga no NPM. Para efetuar logins posteriores, os mesmos dados são pedidos, e o comando é:

$       npm login

Agora podemos publicar nossa biblioteca, digitando o comando npm publish e passando o caminho do arquivo .tgz gerado:

$        npm publish .\dist\teste\teste-0.0.1.tgz

Bom, o artigo ficou um pouco grande porque expliquei algumas coisas com detalhes, mas espero ter ajudado! Abraços!




Links de referência: