Top Posts

Going to SP… novo rumo

Continue lendo

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

Posted by camilolopes | Posted in AngularJS, Series | Posted on 15-11-2013

6

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!! 

Fazendo Deploy de sua aplicação JEE no OpenShift

Posted by camilolopes | Posted in Java | Posted on 23-09-2013

0

Olá Pessoal

O post de hoje é para quem deseja fazer deploy de sua app na nuvem e sem custo. O openShift é uma plataforma de cloud da RedHat que permite fazer isso de forma gratuita, até 1 GB de Storage. Show, heim? Nunca tinha usado o OpenShift, e daí resolvi fazer o deploy da app I4JSFDemo, que é um exemplo de uso da API I4JSF.

Lets go…

Primeiro passo

Ter uma conta no OpenShift. Abra sua conta, it is very easy.

Segundo Passo

Você precisa  gerar o SSH. Se você usa o Git com o GitHub certamente vai ter um id_rsa e id_rsa.pub  em .ssh. Portanto abra o arquivo .id_rsa.pub e deixe aberto por enquanto.

Terceiro Passo

Clique em create application e siga os passos

openshiftcreateapp

Escolha em browser by tag a opção Java. Assim teremos os servers Java:

 

openshifttagjavaappserver

No meu caso vou escolher TomCat .

Quarto Passo

Após ter criado a app vá em My Application e veja que ela está lá. Clique na setinha que está apontando para a direita e assim teremos detalhes da app. Veja:

 

openshiftgitrepo

Observe que você tem o url do repositório. Faça o clone desse repositório.

Quinto Passo

git rm -r src/ pom.xml

Assim vamos remover os arquivos default criado pelo OpenShift.

Sexto Passo

Coloque seu .war em webapps

Sétimo Passo

Faça um commit  e push

 git commit –am “my first commit openshift”  git push

Aguarde o push terminar e observe que o openshift vai fazer build da sua aplicação e o deploy. 

 

openshiftpush

 

openshiftbuildsucess

Aqui eles explicam o que acontece quando faz um push:

https://www.openshift.com/developers/deploying-and-building-applications

Outro link legal:

https://github.com/openshift/origin-server/blob/master/cartridges/openshift-origin-cartridge-jbossews/README.md

Resultado:

openshiftresultapp

 

Link da APP

http://i4jsfdemo-camilolopes.rhcloud.com/i4jsfdemo/

Conclusão

  • – Deploy muito fácil;
  • – Boa documentação;
  • – Podemos logar na aplicação via command line com o Putty por exemplo;
  • – É grátis até 1GB de Storage;

Se você pretende fazer uma POC a versão free atende bem.

No mais é isso. Espero que tenham gostado do post.

See ya!!

Abraços