Entendendo Maven archetypes AngularJS para Java Developers

+

Olá Pessoal,

O post de vou apresentar os archetypes maven que criei com angularJS. Espero que gostem e vejam a diferença de

cada um.

Lets go…

Entendendo os archetypes

Bom, além de responder ao leitor, resolvi fazer um post para explicar cada archetype que criei e a diferença entre eles. Cada um nasceu a partir da necessidade de projetos reais, quando tivemos que fazer só uma POC e não queríamos dar copy/paste em outro projeto, mas sim ter um esqueleto funcionando e com mínimo de trabalho possivel, pois há copy/paste que ter que fazer os ajustes é algo muito estressante. Vamos entender aqui cada um deles:

archetype-webApps-Module

Esse aqui nasceu com objetivo de deixar em aberto o que vai ser usado no front-end, mas o back-end, com o que é básico, já vem configurado. Por exemplo: Hibernate, Spring, Jersey (se for o caso), DBUnit, DAO Generic, Service Generic, etc, mas o front-end fica em aberto para você escolher. Esse archetype atende quando precisamos usar o recurso de módulos (module) do maven, e por default vem com webapps-core que é para back-end e webapps-web para front-end. O principal é conhecido como parent, e no pom.xml dele tem as libs em comum para os dois módulos.

Iai, vai criar um novo projeto e não sabe o que vai ser no front-end e quer usar a estrutura de modules?

Recomendo usar esse archetype.

https://github.com/camilolopes/archetype-webapps-module

archetype-webapps-module-angularjs

Esse aqui tem tudo o que tem no archetype anterior, a diferença é que vem com o angularJS configurado pelo Yeoman tools. Então, se vai começar um projeto com angularJS e separado por modules back/front-end, recomendo usar esse archetype. Claro, considerando que a estrutura do front-end vai seguir o que o Yeoman gera, e já vem com suporte ao twitter boostrap, mas você vai precisar que o bower baixe as dependências, portanto build seu projeto antes via grant.

https://github.com/camilolopes/archetype-webapps-module-angularjs

archetype-webapps-java-angularjs

https://github.com/camilolopes/archetype-webapps-java-angularjs

Esse aqui tem tudo o que os outros archetypes tem em termos de framework, exceto que esse não usam módulos do Maven. É um único projeto JEE, como estamos acostumados. Ele usa o angularjs 1.2.x. e segue uma estrutura simples de organização dos controllers, services e outros JS.

Quando usar?

Quando você precisa criar um projeto JEE com angularjs, mas que não precisa ser separado em módulos e não quer usar o Yeoman. Aqui é a estrutura é bem pura, ou seja, nada do front-end é gerado por ferramentas.

archetype-webapps-java-angularjs-yeoman

https://github.com/camilolopes/archetype-webapps-java-angularjs-yeoman

Tem tudo o que o archetype-webapps-java-angularjs tem, a diferença é que o front-end é gerado pelo yeoman com AngularJS 1.0

archetype-webapps-simple-angularjs-yeoman

https://github.com/camilolopes/archetype-webapps-simple-angularjs-yeoman

Esse aqui tem tudo que o anterior tem, exceto que não vem com os frameworks Java.

archetype-webapps-simple-angularjs

https://github.com/camilolopes/archetype-webapps-simple-angularjs

Esse aqui é o mais simples archetype. Ele não tem nada de framework java, apenas o AngularJS configurado e a estrutura dos packages para JS. Se você quer testar o angularJS da maneira mais simples, esse é o archetype ideal.

Pronto pessoal. Essa é a lista de archetypes que criei para facilitar a nossa vida com AngularJS. Espero que ajudem também no dia a dia de vocês.

Abracos. See ya!!

Série AngularJS: Conheça Yeoman

olá Pessoal,

O post de hoje é bem rápido, o objetivo é mais apresentar um ferramenta muito bacana para desenvolvimento de web apps com JS. E mais especifico com AngularJS.

Lets go…

Yeoman

É uma ferramenta que permite criarmos projetos para web apps de maneira organizada, fácil e rápido. Para entender a utilidade do Yoeman é preciso tentar responder a pergunta: como você gera seu projeto angularJS hoje?

Sabemos que não há segredo em sair usando o angular, mas pense em desenvolver uma aplicação web que tende a ter vários arquivos, pastas etc. Se não temos uma estrutura bem organizada do projeto, certamente vamos ter problemas quando precisar encontrar alguma coisa ou até explicar para um novo desenvolvedor que acabou de chegar. O Yoeman tenta resolver isso. Claro que tem muitas outras features como estrutura de unit test, build etc. No Java seria algo como o maven. Tem um vídeo que acho fantástico e prático que compartilhei a seguir. Assitam e tirem suas próprias conclusões:

Em resumo o Yoeman juntou Bower + grunt

O bower (criado pelo Twitter): resolve problemas de dependências

grunt: é usado para build, preview e testar o projeto.

Apresentação sobre o Yoeman Confira aqui
Particularmente estou experimentando a ferramenta e tenho gostado.

Aproveitando, queria sua ajuda para responder uma simples pesquisa de 10 segundos. Qual curso você gostaria de ver no meu imasters pro em 2014? Responda aqui .  Obrigado pelo help. 🙂

Abracos. See ya!!

Série AngularJS: Maven archetype com AngularJS e Yeoman

 

Olá Pessoal,

Iai vai desenvolver sua aplicação com AngularJS e Java, mas vai no archetype do maven e não tem nada? Já era, agora tem rs. Acabei de criarum archetype Maven com AngularJS + Yeoman

Lets…

Overview 


O motivo de criar esse archetype é que tenho trabalhado bastante nos últimos 4 meses com AngularJS e back-end Java e tem surgido novos projetos, alguns pequenos, outros médio porte, e ter que fazer setup toda hora é meio chato, heim? Então, para unir o útil ao agradável, resolvi um problema aqui no projeto para todos os projetos que vão trabalhar usando módulos no maven e o back-end será Java com front-end AngularJS, para evitar aquele tempo gasto em setup (mesmo que seja uma hora, já compensa). Eu já fiz outros archetypes e estão no meu github.

O que tem de legal nesse archetype?

Bem, o que tem de legal é o seguinte:

  • Hibernate 4.x já vem configurado com o Spring;
  • Spring Core 3.x;
  • MySql 5.x
  • DBUnit (configurado e pronto pra sair usando);
  • DAO Generic e Service Generic;
  • Jersey 1.x
  • AngularJS 1.0.x
  • Yeoman Tools
  • Twitter Bootstrap
  • Flyway (para db migration – opcional a configuração)

Só isso que vem de legal, rs. No AngularJs eu optei pela versão estável ao invés da Release candidate.

Como usar?

Simples. Para não repetir aqui no blog o que já escrevi no readme.md do projeto, siga os passos da instalação do archetype no seu repositório maven local.

Instalado. E agora?

Vamos criar um projeto e fazer uns ajustes como com qualquer template que vem com informações default e precisam ser ajustadas para atender ao nosso projeto.

Passo 1

Crie um novo projeto maven e escolha a opção All Catalogs e em seguida digite br. para filtrar e aparecer o archetype que acabou de instalar.

archetypeangularjscatalog

Passo 2

Escolha o archetype e preencha com as informações do seu projeto.

Passo 3

Clique em finish.

Passo 4

Seu projeto vai estar quebrado, conforme a imagem a seguir

archetypeangularjsprojectfailure

Passo 5

Abra o pom.xml do projeto webapps-web e remova a dependência webapps-core que tem configurações default do archetype

archetypewebappscoreangularjsremoved

Passo 6

Adicione a dependência do seu projeto

archetypeangularjswebappscore

Passo 7

Seu projeto deve estar assim agora:

archetypeangularjsprojectresult

Dentro de webapps-web/webapps temos a pasta apps e toda a estrutura gerada pelo Yeoman.

Passo 8

Vá na raiz do projeto e execute:

mvn tomcat:run

Aplicação deve subir agora acesse: http://localhost:8080/webapps-web/

Pronto, agora é só usar.

Claro que você vai precisar especificar as informações de banco de dados, estrutura do seu packages, etc. Vou assumir que você já conhece os frameworks(spring, hibernate, jersey etc) que o archetype aborda e sabe alterar, afinal de contas você não vai criar um projeto com Spring se não sabe mexer com o framework, concorda? Para facilitar, deixei comentários nos arquivos .xml, onde você deve alterar.

Download Archetype Maven AngularJS 

https://github.com/camilolopes/archetype-webapps-module-angularjs

Em breve stou subindo outros archetypes para projetos pequenos, aguardem mais alguns dias :D.  Se quiser ser avisado assim que publicar pode me acompanhar no github ou assinar o blog. 

Abracos. Vou ficando por aqui.

Série AngularJS: Dependency Injection

 

Olá Pessoal,

No post de hoje vamos ver como usar  dependecy Injection. E para isso vamos precisar aprender como criar services .

Lets go…

 Starting…

E para não ser diferente vamos dar continuidade ao nosso projeto recipeangularexample.  Para o exemplo de hoje vamos precisar apenas alterar o nosso arquivo recipeController.js, alterar o controle existente e criar mais um.

Development

Para criar o serviço é preciso criar um factory, portanto adicione no app.js

O que estamos fazendo aqui? Criamos um array chamado users e duas funções: uma retorna todo o array e outra apenas o primeiro elemento.

Essa é a uma simples estrutura da criação de serviço. UserService é o nome do serviço e é através desse nome que vamos chamar no controller.

Alterando o recipeController.js

Vamos alterar o controle recipeController adicionado a chamada ao UserService, portanto deixe assim:

var recipeController  = function ($scope,UserService){

       $scope.name=””;

//invocando o método do serviço que retorna todos os users

       $scope.users=UserService.all();

//restante do código omitido

};

recipeController.$inject=[“$scope”,”UserService”];

Observe que passamos o UserService no parâmetro da função. Isso é para que o Angular possa fazer IoC.  $inject que colocamos fora do controller é de fato onde o IoC é injetado pelo framework, e precisamos fazer isso para que o objeto seja instanciado.

Vamos adicionar outro controller que terá como objetivo exibir apenas o primeiro elemento do array, portanto adicione:

var anotherController =function ($scope,UserService){

//invocando o metodo do service que retorna apenas o primeiro elemento

       $scope.firstUser = UserService.first();

};

anotherController.$inject=[“$scope”,”UserService”];

Nada de diferente, o código completo deve estar assim:

var recipeController  = function ($scope,UserService){

       $scope.name=””;

       $scope.users=UserService.all();

       //estou considerando que você fez o $watch do post anterior

       $scope.$watch(“name”,function(newValue,oldValue){

             if($scope.name.length > 0){

                    $scope.greeting = “Greeting ” + $scope.name;

             }

       });

};

recipeController.$inject=[“$scope”,”UserService”];

var anotherController =function ($scope,UserService){

       $scope.firstUser = UserService.first();

};

anotherController.$inject=[“$scope”,”UserService”];

Atualizando o arquivo serviceio.html

Vamos colocar carne nesse HTML:

<body>

<div ng-controller=“recipeController”>

<ul ng-repeat=“user in users”>

       <li>{{user}}

</ul>

</div>

<div ng-controller=“anotherController”>

First User:{{firstUser}}

</div>

</body>

 

Para cada div temos um controller.

Testando

angularjsrecipeserviceiocresult

Fantástico, não? Se for a primeira vez que você está vendo o código acima, este pode parecer estranho e confuso, mas com prática e lendo a documentação você se acostuma e vê que é bem lógico. Não há outra forma de acostumar com a estrutura do código e entender se não for praticando e lendo a documentação do framework.

Vou ficando por aqui. Espero que tenham gostado do post e estejam curtindo a série.

Abraços.

Série AngularJS: Aplicação JEE com AngularJS

Olá Pessoal,

No post de hoje vamos ver como persistir os dados que estão no nosso front-end com AngularJS em uma base de dados, mas o nosso back-end é Java usando Spring, Hibernate e Jersey.

Lets go…

Starting…

Vou considerar que você já conhece Spring e Hibernate, portanto o post irá direto ao assunto. Veremos apenas como fazer com que os dados do front-end chegue ao back-end. É necessário que você tenha o Jersey no Controller do lado do Server-side. Fiz um post sobre o AngularJS e Jersey.

Antes de começar

  1. Crie um projeto webapp, de preferência com o maven;
  2. Adicione as dependências do Spring, hibernate, banco de dados, Jersey;
  3. Tenha a lib do angular no projeto ou use a versão online.

O nosso projeto

É muito simples, apenas um formulário que cadastra um customer. Veja o projeto:

angularjcustomerproject

Vou considerar que você já tem a camada de serviço DAO e application-context do Spring devidamente criados e funcionando.

Adicionando Dependência no pom.xm Jersey-Spring

<dependency>

<groupId>com.sun.jersey.contribs</groupId>

<artifactId>jersey-spring</artifactId>

<version>1.8</version>

<exclusions>

<exclusion>

<groupId>org.springframework</groupId>

<artifactId>spring</artifactId>

</exclusion>

<exclusion>

<groupId>org.springframework</groupId>

<artifactId>spring-core</artifactId>

</exclusion>

<exclusion>

<groupId>org.springframework</groupId>

<artifactId>spring-web</artifactId>

</exclusion>

<exclusion>

<groupId>org.springframework</groupId>

<artifactId>spring-beans</artifactId>

</exclusion>

<exclusion>

<groupId>org.springframework</groupId>

<artifactId>spring-context</artifactId>

</exclusion>

</exclusions>

</dependency>

Configurando o Jersey-Spring

No arquivo web.xml deixe assim:

<servlet>

<servlet-name>jersey-servlet</servlet-name>

<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>

<init-param>

<param-name>com.sun.jersey.config.property.packages</param-name>

<!– Aqui é o package onde vai ficar o controller –>

<param-value>com.camilolopes.jersey.services</param-value>

</init-param>

<init-param>

<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>

<param-value>true</param-value>

</init-param>

</servlet>

Crie a classe CustomerController.java conforme a seguir:

@Controller

@Path(“/service”)

public class CustomerController {

@Autowired

@Qualifier(“customerService”)

private CustomerService customerService; //substituir pela sua classe de Service gerenciada pelo Spring

@GET

@Produces(MediaType.APPLICATION_JSON)

public List<Customer> getCustomer() {

List<Customer> list = customerService.getListCustomers();

return list;

}

@POST

@Consumes(MediaType.APPLICATION_JSON)

public void saveCustomer(Customer customer){

customerService.save(customer);

}

public CustomerService getCustomerService() {

return customerService;

}

public void setCustomerService(CustomerService customerService) {

this.customerService = customerService;

}

}

 

Se você viu o nosso post com Jersey e conhece WebService já sabe o que significa essa classe.  Em poucas palavras, é através dessa classe que o front-end e o back-end se comunicam através de um objeto JSON. Então quando o angular precisa enviar algo para o back-end ele vai precisar chamar algum serviço disponível nessa classe, e temos apenas dois: um GET e outro POST.

Criando o app.js

 

       $app = angular.module(‘app’,[‘ngResource’]);

$app.config(function($routeProvider,$httpProvider,$locationProvider){

//routes

$routeProvider.

when(‘/’,{templateUrl:’view/customers.html’,controller:customerController}).

when(‘/create’,{templateUrl:’view/form.html’,controller:customerController}).

when(‘/list’,{templateUrl:’view/customers.html’,controller:customerController}).

otherwise(

{

redirectTo:’/’

});

$httpProvider.responseInterceptors.push(function($q,$rootScope){

return function(promise){

return promise.then(function(response){

return (response);

},function(response){

$data = response.data;

$error = $data.error;

if($error && $error.text){

console.log(“ERROR: ” + $error.text);

}

else{

if(response.status=404)

console.log(“page not found”);

}

return $q.reject(response);

});

};

});

});

Esse código acima apenas cria rotas com base no que for chamado no browser. Por exemplo, se chamarmos /create vai ser carregado a página form.html e o controller  customerController que ainda vamos criar.

A outra função é, em caso de erro no response, podermos exibir um conteúdo customizado. A novidade que temos nesse arquivo é:

$app = angular.module(‘app’,[‘ngResource’]);

Lembra que nos posts anteriores passávamos [] para o segundo parâmetro do module? Agora estamos dizendo que vamos usar ng-resource para conectar a um WebService.  Adicione ao seu projeto angular-resource.js  ou use a versão online:

<script src=“http://code.angularjs.org/1.0.6/angular-resource.min.js”></script>

Criando customerController.js

Vamos agora criar o controller do angular, portanto crie um arquivo JavaScript chamado customerController.js. Não vamos organizar o projeto, pode colocar dentro de webapp mesmo:

function customerController($scope,$resource,$location){

//estamos criando um objeto e linkando com o webservice CustomerController.java

Customer = $resource(“rest/service/”);

//estamos criando uma função que carrega todos os customers.

$scope.loadAll = function(){

Customer.query(

function(data){

$scope.rows = data;

});

};

//quando chamado cria um novo customer e salva.

       $scope.newOne = function() {

var c = new Customer();

//estou atribuindo o nome digitado ao atributo do domain Customer.

c.name = $scope.nameCustomer;

c.$save();

};

}

No inicio parece estranho, mas é porque é diferente do que estamos acostumados. Coloquei a explicação em modo de comentário inline para facilitar o entendimento. Não se preocupe se no inicio se sentir desconfortável com a estrutura, também me senti, mas com o tempo fui aprendendo melhor e vendo que faz sentindo a forma que o angular trata o binding.

Criando o arquivo index.html

Vamos carregar as libs, então esse arquivo terá libs e a ng-view:

 

<html ng-app=“app”>

<head>

<meta charset=“UTF-8”>

<script src=“http://code.angularjs.org/1.0.6/angular.min.js”></script>

<script src=“app.js”></script>

<script src=“customerController.js”></script>

</head>

<body>

<a href=“#/create”>Create</a>

<a href=“#/list”>List</a>

<script src=“http://code.angularjs.org/1.0.6/angular-resource.min.js”></script>

<div ng-view></div>

</body>

</html>

Criando o form.html

<body ng-controller=“customerController”>

<h2>Register Customer</h2>

<form  name=“customerform”>

<div>

<label>Name</label>

<input name=“name” ng-model=“nameCustomer” require/> {{nameCustomer}}

</div>

<div>

<label>Phone</label>

<input name=“phone” ng-model=“phoneCustomer” /> {{phoneCustomer}}

</div>

<div>

<label>E-mail</label>

<input name=“email” ng-model=“emailCustomer” type=“email” required /> {{emailCustomer}}

</div>

<div>

<input type=“button” value=“Save” ng-click=“newOne()” ng-disabled=“customerform.$invalid”/>

</div>

</form>

</body>

 

 Criando customers.html

Aqui vamos listar os customers cadastrados

<div ng-init=“loadAll()”>

<table id=“tableData”>

<thead>

<tr>

<th>ID</th>

<td>Nome</td>

</tr>

</thead>

<tbody>

<tr ng-repeat=“row in rows”>

<td>{{row.id}}</td>

<td>{{row.name}}</td>

</tr>

</tbody>

</table>

</div>

 

Observe que temos ng-init. Essa diretiva invoca o método que carrega todos os customers.

Em seguida temos a diretiva ng-repeat que funciona como um forEach do Java rows; é a variável que criamos no customerController.js

Testando

Assumindo que seu BD está up, suba a aplicação (caso tenha criado um maven Project, apenas digite mvn tomcat:run via linha de comando):

angularjscustomerrunning

Clique no link Create

angularjscustomercreate

Observe a url e o botão save. A url tem alguma relação com as rotas que criamos? E o botão save, por que está desabilitado?

Ele está desabilitado porque fizemos isso no form.html:

<input type=“button” value=“Save” ng-click=“newOne()” ng-disabled=“customerform.$invalid”/>

Olhe para a diretiva ng-disabled. Ali estamos dizendo que se o formulário for invalid desabilite o botão. E o que é um formulário inválido? Nesse caso, se os campos que marcamos como required não estiverem preenchidos, é um form inválido. Observe que quando preencher os campos requeridos, automaticamente o botão fica habilitado:

angularjscustomerformvalid

Clique em save. Se clicar mais de uma vez acontece isso:

angularjscustomerlist

Click no link List

Poderiamos redirencionar usando $location.path(“nomeDaRota”);

Apesar de termos vários outros atributos no form, salvamos apenas o name. Mas sinta-se a vontade em praticar e salvar os demais.  Conferindo no banco:

angularjscustomerbd

Pronto. Salvando dados no BD com AngularJS, Spring, Jersey, Hibernate. Simples, não?

O projeto completo está no meu GitHub no repositório dedicado às minhas brincadeiras com angularJS: https://github.com/camilolopes/workspaceAngularJs

Sempre estarei subindo projetos novos, brincando com o framework… Se quiser acompanhar basta me seguir no github.

Enfim, espero que tenham gostado do post.

Abraços, see ya!!