Autenticação com Spring Boot, Spring Security e AngularJS - Parte 2

Concluindo a rotina de autenticação, agora iremos criar a camada de frontend, usando o AngularJS.

Criando a Factory


O primeiro processo é criar uma camada para acesso ao serviço de autenticação, o mesmo se encontra na url /login, o código abaixo representa uma factory para encapsular o acesso a camada backend:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
(function(){
 
 angular.module("auth").factory("authAPI", authAPI);
 
 authAPI.$inject = ["$http"];
 
 function authAPI($http){
  
  return{
   
   authenticate: function(params){
     
    var req = {
      url: '/login',
      method: 'POST',
      headers: {'Content-Type': 'application/x-www-form-urlencoded'},
      data: $.param(params)
    };
    
    return $http(req);
   }
  };
 };
})();

Vamos analisar o código:
  • Criamos um factory para encapsular o acesso a camada de backend;
  • Linha 5: Injeção do componente $http;
  • Linha 11: Declaração na função chamada autheticate, que recebe uma variável chamada params, que contém os dados que serão enviados ao servidor;
  • Linha 13: Declaração um objecto com os dados do request (url, method, headers, e data);
  • Linha 16: Setamos um header dizendo ao servidor qual o Content-Type que esta sendo encaminhado na solciitação;
  • Linha 17:  Encaminhamos a variável params, porém antes utilizamos a função $.param(), isso é necessário devido ao comportamento padrão do AngularJS de sempre encaminhar dados ao servidor em formato JSON, e neste caso, nosso backend espera pelos parâmetros no corpo da solicitação POST;
  • Linha 20: Retornamos a promisse.

Criando o Controller


Após a factory é necessário criar o controller, como o abaixo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
(function(){
 
 angular.module("auth").controller("authCtrl", authCtrl);
 
 authCtrl.$inject = ["authAPI", "$window"];
 
 function authCtrl(authAPI, $window){
  
  var _self = this;
  
  _self.error    = false;
  _self.login    = login;
  _self.credentials = {};
  
  var fnSuccess = function(response){
   _self.error = false;
   
   //Logica de Redirecionamento
   $window.location.href = '/app/index.html';
  };
  
  var fnError = function(response){
   _self.error = true;
  };
  
  /**
   * Enviar para o servidor.
   */
  function login(){
   authAPI.authenticate(_self.credentials).then(fnSuccess, fnError);
  };
 };
})();

Vamos entender a lógica:

  • Criamos um $controller para ser responsável pela manipulação dos dados vindos do frontend;
  • Linha 5: Temos a injeção dos componentes authAPI e $window;
  • Linha 11: Variável booleana chamada error, este é responsável por exibir a mensagem de erro na página html;
  • Linha 13: Criação da variável credentials, que irá armazenar os dados de login/senha;
  • Linha 15: Criação de uma function chamada fnSuccess, que contém a lógica em caso de sucesso no login;
    • Aqui realizamos o redirect para a página inicial do sistema.
  • Linha 22: Criação de uma function chamada fnError, que contém a lógica de falha no login, nesse ponto apenas é setado o valor da variável error para false;
  • Linha 30: Chamada ao método da authAPI.

Página HTML


A página html possui os inputs e as diretivas que serão utilizadas para manipular as funções do controller:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<div class="panel-body bg-light" data-ng-controller="authCtrl as auth" data-ng-cloak class="ng-cloak">
   <div class="alert alert-danger text-center" data-ng-if="auth.error">
      <i class="fa fa-exclamation-triangle"></i> Atenção! Login ou senha inválidos.
   </div>
   <form data-ng-submit="auth.login()">
      <div class="section row">
         <div class="col-sm-12">
            <div class="form-group">
               <div class="input-group">
                  <span class="input-group-addon">
                     <i class="fa fa-user fa-lg"></i>
                  </span>
                  <input type="text" id="username" name="username" data-ng-model="auth.credentials.username" class="form-control" maxlength="50" placeholder="Digite seu Email de Acesso." />
               </div>
            </div>
         </div>
      </div>
  
      <div class="row">
         <div class="col-sm-12">
            <div class="form-group">
               <div class="input-group">
                  <span class="input-group-addon">
                     <i class="fa fa-lock fa-lg"></i>
                  </span>
                  <input type="password" id="password" name="password" data-ng-model="auth.credentials.password" class="form-control" maxlength="30" placeholder="Digite sua senha." />
               </div>
            </div>
          </div>
       </div>
  
       <div class="section row">
          <div class="col-sm-12">
             <button type="submit" class="btn btn-danger btn-responsive">
                <i class="fa fa-paper-plane"></i> <strong>Entrar</strong>
             </button>
          </div>
       </div>
   </form>
</div>

Vamos entender o conteúdo da página html:
  • Linha 1: Nesta linha temos a declaração do controller através da diretiva data-ng-controller;
  • Linha 2: Temos a declaração da <div class="alert" />, aqui temos a mensagem de erro em caso de falha no login;
  • Linha 5: Aqui temos a declaração do <form />, que contém a diretiva data-ng-submit chamando a função de login();
  • Linha 13: Aqui temos a tag <input /> com a diretiva data-ng-model associando ao objeto auth.credentials.username;
  • Linha 26: Aqui temos a tag <input /> com a diretiva data-ng-model associando ao objeto auth.credentials.password.

Na página html, o design fica a critério do desenvolvedor, os únicos pontos importantes são as informações que serão encaminhadas a API REST de autenticação da lógica de servidor.

Após seguir todos os passos temos um processo de autenticação completo utilizando Spring Boot, Spring Security e AngularJS.

Até próxima.

Autenticação com Spring Boot, Spring Security e AngularJS - Parte 1

Hoje iremos analisar o processo de autenticação em uma aplicação que utiliza SpringBoot, SpringSecurity e AngularJS.

Conhecendo o Spring Security


Em toda aplicação o processo de autenticação é extremamente importante, sendo um dos requisitos não funcionais mais importantes em 80% das aplicações.

Para executar tal tarefa , podemos criar rotinas ou usar frameworks já preparados para os mais diferentes cenários, no caso, vamos analisar o Spring Security, este faz parte dos componentes da plataforma Spring.

Um ponto bem interessante do Spring Security, é que ele pode ser usando em projetos que usam ou não o Spring em sua essência, por exemplo, um projeto feito somente com JEE, pode usar o Spring Security para gerenciar a parte de segurança normalmente, para mais detalhes podemos acessar a documentação oficial:


Integrando o SpringSecurity com SpringBoot


Para utilizar o SpringSecurity em uma aplicação SpringBoot, temos que adicionar o seguinte starter no arquivo pom.xml:

1
2
3
4
<dependency>         
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-security</artifactId>
</dependency>

Configurando o Spring Security


Para configurar o Spring Security, necessitamos criar uma classe com a lógica de segurança, esta deve conter a annotation @EnableWebSecurity:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter{

    private final String[] pagesAuthorizes  = {"/index.html"};
  
    @Override
    protected void configure(AuthenticationManagerBuilder auth) 
    throws Exception {
       auth.inMemoryAuthentication().withUser("usuario").password("123").roles("APP");
    }
 
    @Override
    public void configure(WebSecurity web) 
    throws Exception {
       web.ignoring().antMatchers("/resources/**");
    }
 
    @Override
    protected void configure(HttpSecurity http) 
    throws Exception {
       http.authorizeRequests()
           .antMatchers(this.pagesAuthorizes)
              .permitAll()
           .antMatchers("/**").hasRole("APP")
              .anyRequest()
              .authenticated()
           .and()
           .formLogin()
              .loginPage("/index.html")
              .loginProcessingUrl("/login")
              .failureHandler(this.customFailureHandler())
              .successHandler(this.customSuccessHandler())
              .permitAll()
           .and()
           .csrf()
              .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
           .and()
           .logout()
              .logoutSuccessHandler(this.customLogoutSuccessHandler())
              .invalidateHttpSession(true)
              .logoutRequestMatcher(new AntPathRequestMatcher("/logout"));
    }
   
    private AuthenticationFailureHandler customFailureHandler(){
       return (request, response, exception) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
    }

    private AuthenticationSuccessHandler customSuccessHandler(){
       return (request, response, authentication) -> response.sendError(HttpServletResponse.SC_OK);
    }
 
    private LogoutSuccessHandler customLogoutSuccessHandler(){
       return (request, response, authentication) -> response.sendError(HttpServletResponse.SC_OK);
    }
}

Vamos analisar cada item da classe acima:

1- Autenticação: Nessa parte, definimos o resource onde o Spring Security irá consulta os dados de autenticação, aqui podemos usar banco de dados, LDAP, etc, em nosso exemplo utilizamos uma persistência em memória:

1
2
3
4
5
 @Override
 protected void configure(AuthenticationManagerBuilder auth) 
 throws Exception {
    auth.inMemoryAuthentication().withUser("usuario").password("123").roles("APP");
 }

2- Exceção de Recursos: Nessa parte, marcamos para o Spring Security excluir da autenticação tudo que esteja dentro o path /resources/, este armazena os recursos estáticos como .js, .jpg, .css, etc:

1
2
3
4
5
 @Override
 public void configure(WebSecurity web) 
 throws Exception {
      web.ignoring().antMatchers("/resources/**");
 }


3- Lógicas de Acesso: Aqui é onde realizamos os mapeamentos de urls, lógicas de sucesso/falha e logout:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 @Override
 protected void configure(HttpSecurity http) 
 throws Exception {
    http.authorizeRequests()
        .antMatchers(this.pagesAuthorizes)
           .permitAll()
        .antMatchers("/**").hasRole("APP")
           .anyRequest()
           .authenticated()
        .and()
        .formLogin()
           .loginPage("/index.html")
           .loginProcessingUrl("/login")
           .failureHandler(this.customFailureHandler())
           .successHandler(this.customSuccessHandler())
           .permitAll()
        .and()
        .csrf()
           .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
        .and()
        .logout()
           .logoutSuccessHandler(this.customLogoutSuccessHandler())
           .invalidateHttpSession(true)
           .logoutRequestMatcher(new AntPathRequestMatcher("/logout"));
 }

Vamos analisar as partes que envolvem as respostas em caso de falha, sucesso e logout.

A interface AuthenticationFailureHandler


Na linha 14 temos o método failureHandler(this.customFailureHandler()), que recebe como parâmetro uma AuthenticationFailureHandler, nossa implementação usando uma expressão lambda ficou da seguinte forma:

1
2
3
 private AuthenticationFailureHandler customFailureHandler(){
    return (request, response, exception) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
 }

Sem utilizar expressão lambda, basta criar um @Component como abaixo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
@Component
public class AsyncAuthenticationFailureHandler implements AuthenticationFailureHandler {

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception)
    throws IOException, ServletException {
     
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
    }
}

Aqui falamos ao SpringSecurity, que em caso de falha no login, o mesmo deve apenas enviar como resposta um HttpStatus 401, que representa falha na autenticação.

A interface AuthenticationSuccessHandler


Na linha 15, temos o método successHandler(this.customSuccessHandler()), este manipula a resposta em caso de sucesso, nossa implementação usando uma expressão lambda ficou da seguinte forma:

1
2
3
 private AuthenticationSuccessHandler customSuccessHandler(){
    return (request, response, authentication) -> response.sendError(HttpServletResponse.SC_OK);
 }

Sem utilizar expressão lambda, basta criar um @Component como abaixo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
@Component
public class AsyncAuthenticationSuccessHandler implements AuthenticationSuccessHandler{

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
    throws IOException, ServletException {
  
       response.sendError(HttpServletResponse.SC_OK);
    }
}

Este encaminha ao frontend um HttpStatus 200, que representa que a tentativa de autenticação foi realizada com sucesso.

A interface LogoutSuccessHandler


Na linha 22, temos o método logoutSuccessHandler(this.customLogoutSuccessHandler()), este manipula a resposta no processo de logout, veja a implementação:


1
2
3
private LogoutSuccessHandler customLogoutSuccessHandler(){
   return (request, response, authentication) -> response.sendError(HttpServletResponse.SC_OK);
}

Sem utilizar expressão lambda, basta criar um @Component como abaixo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
@Component
public class AsyncLogoutSuccessHandler implements LogoutSuccessHandler{

  @Override
  public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
  throws IOException, ServletException {

     response.sendError(HttpServletResponse.SC_OK);
  }
}

Este encaminha ao frontend um HttpStatus 200, que representa  sucesso na operação de logout.

Realizado todo o procedimento acima, temos toda a camada do Spring Security pronta para processar as solicitações vindas do AngularJS.

Até a próxima.

Referências



Utilizando a pg_stat_activity para analisar estatísticas do PostgreSQL

Recentemente precisei analisar e dimensionar as conexões estabelecidas e os processos que estavam sendo executados em cada uma das conexões no PostgreSQL, o banco de dados possui uma série de estruturas que permitem recuperar tais informações estatísticas.

Análise das Conexões Estabelecidas


Um cenário comum quando precisamos analisar a performance dos nossos sistemas, é o levantamento das conexões estabelecidas com o banco de dados, tal informação é útil para:

  •  Analisarmos se o pool esta corretamente a dimensionado;
  • Analisar quantas conexões estão sendo utilizadas;
  • Analisar se existem muitas conexões alocadas e ociosas com a base de dados.
Em muitas aplicações podemos encontrar problemas relacionados a integração entre o aplicativo e o banco de dados.

Coleta de Estatísticas no PostgreSQL


O  PostgreSQL possui uma série de views que nos fornecem dados estatísticos e gerenciais sobre as base de dados, para mais detalhes podemos consultar o site oficial, onde temos todos os dados que podemos utilizar para o monitoramento:


Vamos nos concentrar na view pg_stat_activity, ela fornece informações sobre todas as conexões alocadas e o que esta sendo executado em cada uma delas.

Para ver o funcionamento, criei um database chamado bd_analise, e agora vamos rodar a seguinte query em nosso banco de dados:


select 
    datid, datname, pid, usename, query_start, waiting, state, query 
from 
    pg_stat_activity;

Como resultado, teremos apenas uma simples conexão com nosso banco de dados, isto porque, não temos nenhuma aplicação conectada no momento, veja abaixo:

Resultado da execução da query sobre a view pg_stat_activity.

Agora para simular um ambiente real, irei executar um aplicativo que irá criar um pool de conexões com 10 conexões, e novamente executar a query de estatística, o resultado será como o abaixo:

Resultado após criação de um pool com 10 conexões.

Podemos analisar algumas informações importantes no resultado:

  • datid: Identificação da conexão;
  • datname: Nome da base de dados;
  • pid: Identificação do processo de execução;
  • usename: Nome do usuário;
  • query_start: Horário em que a consulta foi iniciada;
  • waiting: Verifica se a conexão esta em espera;
  • state: Estado atual da conexão;
  • query: Query mais recente executada.

Obs: Existem outras colunas que podem ser utilizada para uma análise mais detalhada, isso depende da informação que necessitamos encontrar na análise.

Além da view pg_stat_activity, existem outras que possuem finalidades diferentes, para mais detalhes, consulte a documentação oficial, lá existem explicações detalhadas para as diversas análises possíveis.


Resolvendo problemas entre QueryDSL e SpringBoot 1.4.x

Hoje iremos analisar e resolver um problema relacionado a migração para a ultima versão estável do SpringBoot e a integração com a API QueryDSL.

O que é a QueryDSL


A QueryDSL é uma API que permite a escrita de instruções JPQL/SQL de forma fluente, facilitando a escrita de querys complexas e deixando essa operação similar a chamadas de métodos do modelo de domínio, para detalhes segue o site oficial:


Evolução entre QueryDSL 3.x.x e 4.x.x


Na evolução da QueryDSL, houveram algumas mudanças significativas em , dependência, estrutura e código fonte, vamos analisar alguns deles:

QueryDSL 3.x.x:

Dependência Maven para a QueryDSL 3.x.x.

Interface Predicate para a QueryDSL 3.x.x.

Nesse exemplo notamos que a interface Predicate esta localizada no packagecom.mysema.query.types.Predicate.


QueryDSL 4.x.x: 

Dependência Maven para a QueryDSL 4.x.x. 


Interface Predicate para a QueryDSL 4.x.x.

Nesse exemplo notamos que a interface Predicate esta localizada no packagecom.querydsl.core.types.Predicate.

Além das mudanças acima, existem outros pontos mudaram:
  • Forma de uso dos métodos e funcionalidades da API;
  • Escrita de Querys;
  • Package das demais classes e interfaces.

Evolução entre SpringBoot 1.3.x e 1.4.x


Uma das grandes vantagens em utilizar a plataforma Spring, é a rapidez na qual novas versões são lançadas, corrigindo bugs, adicionando novas funcionalidades, melhorando funcionalidades existentes, entre outras.

Recentemente foi lançada a ultima versão do Framework, a versão 1.4.0, esta contém várias melhorias interessantes, para mais detalhes veja o post oficial do site da Pivotal:

https://spring.io/blog/2016/07/28/spring-boot-1-4-released

Este ultimo release do SpringBoot, utiliza como padrão a dependência da QueryDSL 4.x.x, com isso ao realizar a atualização de versão,  devemos analisar os impactos que iram acontecer sobre o sistema caso este utilize a QueryDSL 3.x.x nas operações de persistência.

Até a próxima.


Configurando o arquivo application.properties do SpringBoot

Ao trabalhar com SpringBoot, nos deparamos com várias configurações que devem ser realizadas, com isso, é necessário conhecer o arquivo onde adicionamos as configurações para o projeto.

Tipos de Arquivos


O SpringBoot permite utilizar 2 diferentes tipos de arquivos de configurações:
  • application.properties (Properties);
  • application.yml (Yml).
Por padrão e geralmente o mais utilizado é o application.properties, mas é uma opção que o framework nos fornece, as configurações adicionadas em ambos os arquivos são as mesmas.

Exemplo de Configuração


O arquivo de configuração deve conter as configurações essenciais para o uso do SpringBoot, em seu projeto, vamos ver alguns exemplos:
  • spring.application.name: Nome da aplicação;
  • server.port: Porta qual o container embedded irá alocar;
  • server.compression.enabled: Habilita a compressão da resposta http;
  • logging.level.*: Habilita o Logging já configurado.
Existem uma grande quantidade de informações que podem ser adicionadas ao arquivo de configuração, o uso depende das necessidades do seu projeto.

O SpringBoot disponibiliza uma documentação ampla onde podemos entender todas as configurações do application.properties:


Dicas para criar o application.properties


Um arquivo de configuração é onde adicionamos informações importantes para o projeto, então ele deve ser bem estruturado para que outras pessoas possam manter ou administrar a aplicação, vamos listar alguns detalhes que pode deixar nosso arquivo mais organizado:
  • Identação das configurações;
  • Comentários;
  • Somente configurações necessárias;
  • Referências externas.
Até a próxima.

Referências


Criando um Projeto com Spring Boot

Hoje iremos analisar alguns projetos da plataforma Spring e entender como podemos iniciar um novo projeto utilizando Spring Boot.

A plataforma Spring sempre foi repleta de recursos que a fazem ser uma ótima alternativa para o desenvolvimento de aplicações Java Enterprise, dentro da plataforma temos vários componentes que ajudam no desenvolvimento, vamos listar os mais famosos:
  • Spring Core: Este é o núcleo da plataforma, este é a base para os demais projetos, responsável pela parte de injeção de dependência e  IoC;
  • Spring MVC: Este é o framework MVC apontado por pesquisas, como sendo o mais utilizado em todo mundo, ele trabalha no estilo Action Based, e possui recursos muito interessantes para trabalhar com Web em geral;
  • Spring Data: Este projeto ajuda na parte de persistência, facilitando na integração com os mais diferentes resources de persistência, JDBC, JPA, Bancos NoSQL, entre outras integrações;
  • Spring Security: Este é responsável pela parte de segurança das aplicações, podemos controlar acesso a objetos, autenticação e autorização em aplicações web, token em web service RestFul, entre outras funcionalidades;
  • Spring Boot: Responsável por fornecer uma configuração simplificada de todos os componentes da plataforma Spring, além de permitir a execução da aplicação de diferentes formas, podendo ser Standalone, Embed Container ou Deploy tradicional.
Existem diversos projetos na plataforma Spring, quando vamos iniciar um projeto precisamos configurar as dependências dos recursos que necessitamos, para esta tarefa o Apache Maven é a melhor opção.

Criando um Projeto com Spring Boot


Podemos criar um projeto com Spring Boot de varias formas, as mais comuns são:
  • Criar utilizando a dependência explicita no arquivo pom.xml; 
  • Utilizar algum archetype Maven;
  • Utilizar a ferramenta Spring Initializr.

Utilizando o Spring Initializr


Esta ferramenta é muito útil para criarmos um novo projeto utilizando Spring Boot, vamos analisar sua utilização:

Acessar a url http://start.spring.io/, teremos o seguinte resultado:

Página inicial do Spring Initializr.
Aqui temos as seguintes opções:
  • Gerar utilizando Maven ou Gradle;
  • Escolher a versão do Spring Boot;
  • Definir o GroupId;
  • Definir o ArtifactId;
  • Adicionar as dependências que necessitamos (No caso adicionamos apenas o Web).
Após fazer o download do projeto (no exemplo, Maven Project), teremos o seguinte pom.xml:


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
                                   http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>

 <groupId>com.example</groupId>
 <artifactId>demo</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <packaging>jar</packaging>

 <name>demo</name>
 <description>Demo project for Spring Boot</description>

 <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.3.5.RELEASE</version>
    <relativePath/> 
 </parent>

 <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>1.8</java.version>
 </properties>

 <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
  
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
 </dependencies>
 
 <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
 </build>
</project>

Agora basta importar o projeto dentro da IDE de preferência e dar inicio no projeto com Spring Boot.
 
Até a próxima.

Referências

AngularJS - Formatando Datas com o Filter Date

Olá pessoal, continuando a série sobre AngularJS, hoje iremos analisar como podemos formatar datas vindas do back-end.


Formatação de Datas e Internacionalização


É muito comum nos devolvermos sistemas que necessitam trabalhar com diferentes formatos de datas e valores, esta tarefa geralmente trás algumas dificuldades tanto para o lado back-end como o front-end, é necessário tratar a forma de armazenar essas informações, e também a forma de exibi-las.

O processo exibição, tem que tratar algumas variáveis ainda um pouco mais complexas, como por exemplo:
  • Exibir a data de acordo com o idioma escolhido;
  • Exibir em formatos mais complexos de acordo com lógicas de negócio.


AngularJS e o Filter Date


Com AngularJS formatar as datas a serem exibidas é algo bem simples, pois o framework disponibiliza um filter que ajuda a realizar a formatação de um informação apenas invocando o filter date.

Vamos analisar o exemplo abaixo da utilização do filter date:

1- Código html com o uso do filter date:



<!DOCTYPE html>
<html data-ng-app="app">
   <head>
      <title>AngularJS - Formatando Datas</title>
      <link rel="stylesheet" href="../resources/css/bootstrap.min.css" />
   </head>
   <body>
    <table class="table table-bordered" data-ng-controller="appCtrl as ctrl">
     <thead>
      <tr>
       <th>Formato (dd/MM/yyyy HH:mm:ss)</th>
       <th>Formato 2 (Data completa)</th>
       <th>Formato 3 (Horário)</th>
       <th>Formato 4 (yyyy-MM-dd)</th>
      </tr>
     </thead>
     <tbody>
      <tr>
       <th>{{ctrl.data | date:"dd/MM/yyyy HH:mm:ss"}}</th>
       <th>{{ctrl.data | date:"fullDate"}}</th>
       <th>{{ctrl.data | date:"HH:mm:ss"}}</th>
       <th>{{ctrl.data | date:"yyyy-MM-dd"}}</th>
      </tr>
     </tbody>
    </table>
    <script  type="text/javascript" src="../resources/js/angular.min.js"></script>
    <script type="text/javascript" src="app.ctrl.js"></script>
   </body>
</html>

2- Código JS com a criação do controller:



(function() {
    'use strict';
    
    angular.module("app",[]);

    angular.module("app").controller("appCtrl", function(){
     
     var self = this;
     
     self.data = new Date();
    });
})();

A parte de formatação de datas com AngularJS é muita ampla e existem diversos formatos que podem ser utilizados, para mais detalhes a documentação oficial possui diversos exemplos do uso do filter datehttps://docs.angularjs.org/api/ng/filter/date.

Até a próxima.

Referências


Código


Criando Módulos e DataSources no Wildfly

Hoje iremos ver como criar um Módulos e DataSources no Wildfly Application Server.

O que é um Módulo ?


Módulos no Wildfly são recursos que podem ser utilizados em diversos lugares dentro da instância em execução do Container, eles podem ser reaproveitados em diversos lugares, tais como: artefatos, datasources, entre outros.

Criando um novo Módulo


A criação de módulos no Wildfly é uma tarefa simples, em nosso exemplo, iremos criar um módulo referente ao Driver JDBC do PostgreSQL, para isso deve-se executar os seguintes passos:

1- Acessar o diretório: {WILDFLY_HOME}/modules/system/layers/base:
Diretório base.

2- Criar a estrutura org/postgresql/main, e adicionar o driver(.jar) do PostgreSQL dentro do diretório main:
Driver do banco de dados PostgreSQL.

3- Ainda no diretório main, criar o arquivo module.xml com o seguinte conteúdo:

<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.3" name="org.postgresql">
    <resources>
        <resource-root path="postgresql-9.4.1208.jar"/>
    </resources>
 <dependencies>
        <module name="javax.api"/>
        <module name="javax.transaction.api"/>
    </dependencies>
</module>

4- Após seguir os passos o módulo esta criado e pronto para o uso:

Diretório main com os arquivos.

Agora iremos criar um DataSource referenciando o módulo acima.


O que é um DataSource ?


DataSource é uma fonte de dados onde as aplicações iram buscar informações externas ao Container, estas informações geralmente estão em um banco de dados, mas também podem vir de outras fontes, ao criar DataSources podemos estipular várias características de acesso a fonte de dados, tais como: pool de conexão, registro JNDI, entre outras.


Criando um novo DataSource


1- Acessar o diretório: {WILDFLY_HOME}/standalone/configuration:
Diretório com arquivos de configuração.

2- Editar o arquivo standalone.xml, e adicionar o driver a tag <drivers />:
<drivers>
  <driver name="postgresql" module="org.postgresql">
      <xa-datasource-class>org.postgresql.Driver</xa-datasource-class>
  </driver>
</drivers>

3- Ainda no arquivo standalone.xml, criar um DataSource na tag <datasources />:
<datasources>
  <datasource jndi-name="java:jboss/datasources/testePostgreSQL" 
              jta="true" 
              pool-name="testePostgreSQL" 
              enabled="true" 
              use-java-context="true">
      <connection-url>jdbc:postgresql://localhost:5432/teste</connection-url>
      <driver>postgresql</driver>
      <pool>
        <min-pool-size>5</min-pool-size>
        <max-pool-size>10</max-pool-size>
        <prefill>true</prefill>
      </pool>
      <security>
         <user-name>postgres</user-name>
         <password>admin</password>
      </security>
  </datasource>
</datasources>

Após seguir todos os passos e iniciar o Wildfly, dentro do sistema de administração, na aba configuração, podemos ver o DataSource criado:

DataSource criado e pronto para uso.

Até a próxima.


AngularJS - Trabalhando com ngApp

Hoje iremos continuar a serie de tutorias sobre o AngularJS, nesse tópico falaremos sobre as principal diretiva do framework, que é a ngApp.

O Que são Módulos ?

O AngularJS é um framework baseado em módulos, ou seja, com ele conseguimos dividir nossa aplicação em várias partes, com isso ganhamos em alguns pontos, tais como:
  • Facilidade de Manutenção: Pois conseguimos realizar uma alteração em um módulo especifico, sem a necessidade de alterar o resto da aplicação;
  • Reuso: Conseguimos reaproveitar códigos em varias partes da nossa aplicação, até mesmo podemos reaproveitar em aplicações diferentes, Ex: um módulo de validação onde podemos ter validadores de CPF e CNPJ, que são comuns em sistemas corporativos.

Usando a diretiva ngApp

Como já sabemos para trabalhar com o AngularJS, precisamos criar, utilizar, e estender módulos, e para inicializar uma aplicação, temos que declarar em nossa view a diretiva ngApp, que é a responsável por determinar o escopo da aplicação nas páginas html, vamos acompanhar alguns exemplos:

1- Uso sem código JavaScript


<!DOCTYPE html>
<html data-ng-app="">
  <head>
    <title>AngularJS - Trabalhando com ngApp</title>
  </head>
  <body>
   <h2>Exemplo sem o uso de código JavaScript</h2>
   Soma: {{1 + 10}}
  </body>
  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></scrict>
</html>

No exemplo acima temos alguns detalhes importantes a serem analisados:
  • Declaramos o data-ng-app na tag html, ou seja, em todo escopo da nossa página será possível trabalhar com recursos do framework;
  • Não criamos nenhum código JavaScript, com isso não precisamos atribuir um nome a diretiva, basta apenas declarar como data-ng-app="".

2- Uso com código JavaScript


<!DOCTYPE html>
<html data-ng-app="exemploAngular">
  <head>
    <title>AngularJS - Trabalhando com ngApp</title>
  </head>
  <body data-ng-controller="exemploCtrl as ctrl">
    <h2>Exemplo de uso com código JavaScript</h2>
    Soma: {{ctrl.soma}}
  </body>
  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
  <script type="text/javascript">
    angular.module("exemploAngular", []);

    angular.module("exemploAngular").controller("exemploCtrl", [function(){
        this.soma = (1 + 10);
    }]);
  </script>
</html>

No exemplo acima, temos um código mais complexo e detalhado, vamos nos atentar no funcionamento da diretiva ngApp:
  • No código JavaScript, criamos um módulo chamado exemploAngular, para criação de módulos utilizamos a seguinte sintaxe: angular.module(nome_do_modulo, []), onde:
    • nome_do_modulo: Nome do módulo desejado;
    • []: Outros módulos, que o nosso módulo terá dependência.
  • Referenciamos nosso módulo exemploAngular novamente utilizando a tag html, através de data-ng-app="exemploAngular".

Agora conhecemos o funcionamento da diretiva ngApp, como criar módulos, e como vincular um módulo a nossa pagina html.

Até a próxima.


Código fonte