Olá Pessoal,
No post de hoje veremos como mandar os dados do front-end para o back-end usando o Jersey, mas há outras opções como Spring MVC.
Lets go..
Introdução
A ideia aqui é como mandar o que está na tela para o back-end. O AngularJS não depende do seu back-end, mas de alguma forma vamos precisar que ele converse com o server-side. Como fazer isso? Simples, via objeto JSON usando RESTful. Essa é a forma que podemos mandar os dados que estão na tela para o nosso back-end. Não vou entrar em detalhes do que é um objeto JSON e toda teoria. Basta dar uma “googlada” que há vários posts e artigos sobre o assunto.
Jersey
Vamos usar o Jersey no nosso Controller, que terá como responsabilidade receber um objeto JSON e retornar um objeto JSON para camada de view. Ou seja, é por aqui que o AngularJS vai conversar com nosso back-end e deixar transparente qual linguagem estamos usando (poderia ser Java, PHP, Ruby etc).
Poderíamos usar o Spring MVC retornando um objeto JSON. Pouco importa para o Angular o que teríamos aqui, desde que o objeto retornado fosse JSON.
Na Prática
Vamos deixar de teoria e colocar a mão na massa. Para o Jersey, você precisa ter lido este post. Não vou focar no código do Jersey, pois esse já foi abordado em outro post, portanto considero que você entenda ou já tenha as chamadas dos paths correto no seu controller e o método retornando JSON. A seguir, o método que vamos usar nesse exemplo:
@GET
@Path(“/client”)
@Produces(MediaType.APPLICATION_JSON)
public List<Client> getCliente() {
Client client = new Client();
client.setId(1);
client.setName(“Hello World Camilo”);
ArrayList<Client> list = new ArrayList<Client>();
list.add(client);
return list;
}
Caso não tenha no Controller, adicione. Se você fez o exemplo do post sobre Jersey aqui no blog, basta alterar o método existente conforme acima.
- Crie o arquivo app.js que terá a configuração da nossa aplicação. Esse arquivo deve ficar na raiz, ou seja, em webapp. Claro que você poderia colocar em qualquer outro local, mas vamos manter tudo simples aqui. Veja como ele se parece:
/*
* Nesse arquivo estamos configurando variáveis e métodos GLOBAIS
*/
SERVER_URL=”http://localhost:8080/hellojersey/rest”;
//criando o module para toda app
$app = angular.module(‘app’,[]);
//criando a routes
$app.config(function($routeProvider,$httpProvider,$locationProvider){
//definindo as rotas
$routeProvider.
when(‘/’,{templateUrl:’view/customers.html’,controller:customerController}).
when(‘/clientes’,{templateUrl:’view/hello.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;
// coloquei os alerts para me certificar que a função foi chamada
if($error && $error.text)
alert(“ERROR: ” + $error.text);
else{
if(response.status=404)
alert(“Page not found”);
}
return $q.reject(response);
});
};
});
});
$app.run(function($rootScope){
$rootScope.server=function(url){
alert(SERVER_URL + url);
return SERVER_URL + url;
};
}
);
SERVER_URL é uma variável global que criamos e que tem o caminho do nosso serviço REST. Observe que criamos uma variável Server que vai concatenar com o valor passado, por exemplo. Para chamar um serviço GET disponível diretamente, a url é assim:
http://localhost:8080/hellojersey/rest/hello/client
Mas, a ideia é fazer que isso aconteça via AngularJS de maneira transparente. No código anterior, quando criamos as routers, falamos que quando chamar raiz “/”, o conteúdo do arquivo view/customers.html deve ser exibido na mesma página. E quando chamar /clientes deve ser o conteúdo do arquivo hello.html.
Criando o customerController.js
Vamos criar o nosso controller
function customerController($scope,$http,$routeParams,$location){
$scope.rows=null;
$scope.row=null;
$scope.loadAll = function(){
/* esse é o cara que chama o service rest
* Observe que ele concatena o valor com o que foi definido na variável SERVER
*/
$http.get($scope.server(“/hello/client”)).success(function(data){
$scope.rows=data;
alert(“loadALL”);
}).error(function(data){
alert(“Error…”);
console.log(data);
});
};
}
É aqui que acontece a magia. Observe que passo o caminho do meu serviço,
$http.get($scope.server(“/hello/client”)).success(function(data)
O resto será concatenado com a variável global SERVER_URL.
Criando as páginas HTML
Vamos criar três arquivos HTML
- index.html: teremos um link que ao ser clicado vai exibir todos os clientes, ou seja, por baixo ele chama o nosso serviço rest que retorna todos os clientes;
- customers.html: tem uma tabela que exibe os clientes cadastrados;
- hello.html é apenas mais um arquivo para teste.
index.html
<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>
<li><a href=“#/clientes”>Clientes</a></li>
<div ng-view></div>
</body>
</html>
customers.html
<h2>AngularJS Customers</h2>
<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}}
</tr>
</tbody>
</table>
</div>
Hello.html
<body>
hello, incluiu o conteudo de hllo.htm
</body>
Veja a estrutura do projeto:
Testando
Execute mvn tomcat:run via linha comando ou Eclipse
http://localhost:8080/hellojerseyangularjs/
Vai aparecer os alerts que inserimos
Veja o resultado, e melhor: sem sair da página. Click no link clientes e veja o resultado
Pronto, assim terminamos de fazer AngularJS conversar com o nosso back-end de maneira simples, fácil e transparente.
GitHub
https://github.com/camilolopes/workspaceAngularJs
Abraços, see ya!!!
Camilo,
Por que usar Angular + Rest e não utilizar o JSF2?
Poderia me esclarecer essa duvida?
Olá Julio,
São tecnologias com conceitos diferentes.JSF 2 pra mim, hoje é algo do passado que atendeu demanda e necessidade quando estavamos naquela transição la de jsp, servlet, struts, jsf 1 etc. Hoje não vejo necessidade de adotar um jsf 2 para um app.
Pra vc entender a diferença tem que entender o que angularjs resolve e JSF, apesar que o resultado é front-end, mas não quer dizer que são iguais.
abraço,