Posted by Clayton Casteli On August - 6 - 2015 6 Comments

Nesse post vamos falar um pouco sobre criação de uma aplicação simples com AngularJS e Restful Web Services com Jersey. A aplicação proposta mostra um exemplo simples de CRUD (Create, Read, Update, Delete) envolvendo requisições PUT, DELETE, POST, GET.

Já falamos um pouco sobre AngularJS e criação de serviços com Jersey e JSON nos posts listados abaixo, porém agora vamos expor uma aplicação com esses conceitos.

Introdução a AngularJS

Criar Serviços com AngularJS

Restful Jersey JSON e Tomcat

Vamos abordar os seguintes topicos.

  • Dependências em um projeto Maven
  • Criação do serviço com Jersey
  • Criação da aplicação web

Dependências em um projeto Maven

Para um projeto maven war, as dependencias necessárias são relacionadas abaixo, essas dependencias nos permitem trabalhar em um container com Servlet API 3, JSON Jackson.


<dependency>
			<groupId>org.glassfish.jersey.containers</groupId>
			<!-- if your container implements Servlet API older than 3.0, use "jersey-container-servlet-core" -->
			<artifactId>jersey-container-servlet</artifactId>
			<version>2.19</version>
		</dependency>

		<dependency>
			<groupId>org.glassfish.jersey.media</groupId>
			<artifactId>jersey-media-json-jackson</artifactId>
			<version>2.19</version>
		</dependency>

Cadastramento do repositório


<repository>
	<id>snapshot-repository.java.net</id>
	<name>Java.net Snapshot Repository for Maven</name>
	<url>https://maven.java.net/content/repositories/snapshots/</url>
	<layout>default</layout>
	</repository>

Para o uso de Servlet API 3 não é necessário o uso de web.xml, dessa forma vamos dercartá-lo na confugulação do plugin e usar a anotação @ApplicationPath("") para a Classe de Application onde iremos cadastrar nossas Resources Classes.


<build>
		<finalName>jersey2</finalName>
		<plugins>

			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<inherited>true</inherited>
				<configuration>
					<source>1.6</source>
					<target>1.6</target>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.3</version>
				<configuration>
					<failOnMissingWebXml>false</failOnMissingWebXml>
				</configuration>
			</plugin>
		</plugins>
	</build>

Criação do serviço com Jersey

Para a criação do serviço de atualizações de dados que usaremos em nossa aplicação, quatro classes serão criadas, MyApplication para registros das classes de resources, PessoaResource classe de resources com os serviços, Pessoa como nossa classe POJO com as propriedades de pessoas que iremos trabalhar e Util como nossa classe de repositorio de dados.

A Classe Application pade ser diretamente registrada no web.xml ou registrada via anotação @ApplicationPath e permite o registro de nossos recursos;


@ApplicationPath("myapp")
public class MyApplication extends ResourceConfig {
    public MyApplication() {
        super(PessoaResource.class,
                //jackson
        		JacksonFeature.class

        );
    }
}

A classe PessoaResource e nossa implementação efetiva dos serviços que iremos utilizar;


@Path("/pessoa")
public class PessoaResource {

	// Jackson
	@GET
	@Produces({ MediaType.APPLICATION_JSON/* , MediaType.APPLICATION_XML */ })
	@Path("/all")
	public List&lt;Pessoa&gt; getPessoasJSONP() {

		List&lt;Pessoa&gt; listP = Util.getInstance().getlPessoa();

		return listP;
	}

	// Jackson
	@GET
	@Produces({ MediaType.APPLICATION_JSON/* , MediaType.APPLICATION_XML */ })
	@Path("/{id}")
	public Pessoa getPessoasByIdJSONP(@PathParam("id") int id) {

		List&lt;Pessoa&gt; listP = Util.getInstance().getlPessoa();	

		for (Pessoa p : listP) {
			if (id == p.getId()) {

				return p;
			}

		}

		return null;
	}

	@POST
	@Consumes({ MediaType.APPLICATION_JSON/* , MediaType.APPLICATION_XML */ })
	@Path("/salvar")
	public void salvarPessoasJSONP(Pessoa p) {

		p.setId(Util.getInstance().getId());
		Util.getInstance().getlPessoa().add(p);		

	}

	@PUT
	@Consumes({ MediaType.APPLICATION_JSON/* , MediaType.APPLICATION_XML */ })
	@Path("{id}")
	public void updatePessoaJSONP(@PathParam("id") int id, Pessoa p) {	

		List&lt;Pessoa&gt; listP = Util.getInstance().getlPessoa();

		Pessoa pessoa = listP.get(id);

		pessoa.setNome(p.getNome());
		pessoa.setEmail(p.getEmail());
		pessoa.setIdade(p.getIdade());
		pessoa.setDataCorrente(p.getDataCorrente());
		pessoa.setNascimento(p.getNascimento());

	}

	@DELETE
	@Consumes({ MediaType.APPLICATION_JSON/* , MediaType.APPLICATION_XML */ })
	@Path("/{id}")
	public void deleteJSONP(@PathParam("id") int id) {

		System.out.println("Remover id: " + id);

		Util.getInstance().getlPessoa().remove(id);
	}
}

Nossa classe de gestão de dados, repositório;


public class Util {

	private static Util util = new Util();
	private List&lt;Pessoa&gt; lPessoa = new ArrayList&lt;Pessoa&gt;();

	private void init() {

	Pessoa pessoa = null;
	for (int i = 0; i &lt; 10; i++) {
		pessoa = new Pessoa(i, "Clayton" + i, "email@gmail.com", new Date(), new Date(), i * 3);
		lPessoa.add(pessoa);
	}

	}

	private Util() {
		init();
	}

	public static Util getInstance() {

		if (util == null) {
			util = new Util();
		}

		return util;

	}

	public List&lt;Pessoa&gt; getlPessoa() {
		return lPessoa;
	}

	public void setlPessoa(List&lt;Pessoa&gt; lPessoa) {
		this.lPessoa = lPessoa;
	}

	public int getId(){

		return lPessoa.size();

	}
}

Classe Pessoa;


public class Pessoa {

	private int id;
	private String nome;
	private String email;
	private Date nascimento;
	private Date dataCorrente;
	private int idade;	

	/**
	 *
	 */
	public Pessoa() {
		// TODO Auto-generated constructor stub
	}

	public Pessoa(int id, String nome, String email, Date nascimento, Date dataCorrente, int idade) {
		super();
		this.id = id;
		this.nome = nome;
		this.email = email;
		this.nascimento = nascimento;
		this.dataCorrente = dataCorrente;
		this.idade = idade;
	}

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public Date getNascimento() {
		return nascimento;
	}

	public void setNascimento(Date nascimento) {
		this.nascimento = nascimento;
	}

	public Date getDataCorrente() {
		return dataCorrente;
	}

	public void setDataCorrente(Date dataCorrente) {
		this.dataCorrente = dataCorrente;
	}

	public int getIdade() {
		return idade;
	}

	public void setIdade(int idade) {
		this.idade = idade;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}
}

Criação da aplicação web

Para criação de nossa página web iremos isolar as conteúdo de nossa aplicação AngularJS em arquivos de serviços, controlador, modulo, ... de nossa página web.

js/app.js

var pessoasFormValidation = angular.module("appForm", []);

Para nosso exemplo o arquivo constants não é efetivamente usado, porém e mostrados apenas como forma de mostrarmos sua utilização que e de organizar dados de valores fixos.
js/constants.js

pessoasFormValidation.constant("config", {
	datadefault : new Date("12/12/2014"),
});

//Nosso controller efetivamente tem os métodos, ações e flags de controle para fazer a gestão da tela.
js/controller.js

pessoasFormValidation.controller("ctrlPpessoasFormValidation", function($scope,
		serviceForm) {

	$scope.listaPessoas = {};
	$scope.pessoa = {};
	
	//registra o id de uma pessoa na tabela
	$scope.checkboxIdPessoa = {
			id : -1,
     };
	
	//seleciona uma pessoa na tabela
	$scope.selectPessoa = function(pessoa) {
		
		$scope.pessoa = pessoa;		
		
	};

	//calculate idade
	$scope.calcular = function(pessoa) {

		// $scope.age = 19;

		$scope.idadePessoa = serviceForm.calculate(pessoa);
		$scope.pessoa.idade = $scope.idadePessoa.age;
		//console.log(pessoa.idade);
	};
	
	//getAllPessoas lista todos os dados
	var listarPessoas = function() {
		serviceForm.getAllPessoas().success(
				function(data, status, headers, config) {

					$scope.listaPessoas = data;

				}).error(function(data, status, headers, config) {

			switch (status) {
			case 401: {
				$scope.message = "Você precisa ser autenticado!"
				break;
			}
			case 500: {
				$scope.message = "Erro!";
				break;
			}
			}
			console.log(data, status);
		});
	};
	listarPessoas();
	
	
	
	
	
	//getByIdPessoa
	//savePessoa salva um novo registro de uma pessoa
	$scope.savePessoa = function(pessoa) {
		serviceForm.savePessoa(pessoa).success(
				function(data, status, headers, config) {
					listarPessoas();
					$scope.message = "registro Pessoa savo com sucesso!";
				}).error(function(data, status, headers, config) {
			switch (status) {
			case 401: {
				$scope.message = "Você precisa ser autenticado!"
				break;
			}
			case 500: {
				$scope.message = "Erro!";
				break;
			}
			}
			console.log(data, status);
		});
	};
	
	//updatePessoa atualiza registro de uma pessoa quando selecionado na tabela
	$scope.updatePessoa = function(pessoa) {
		serviceForm.updatePessoa(pessoa).success(
				function(data, status, headers, config) {
					listarPessoas();
					$scope.message = "registro Pessoa savo com sucesso!";
				}).error(function(data, status, headers, config) {
			switch (status) {
			case 401: {
				$scope.message = "Você precisa ser autenticado!"
				break;
			}
			case 500: {
				$scope.message = "Erro!";
				break;
			}
			}
			console.log(data, status);
		});
	};
	
	
	
	//deletePessoa remove um registro de uma pessoa quando selecionado na tabela
	$scope.deletePessoa = function(pessoa) {
		serviceForm.deletePessoa(pessoa.id).success(
				function(data, status, headers, config) {
					listarPessoas();
					$scope.message = "registro Pessoa savo com sucesso!";
				}).error(function(data, status, headers, config) {
			switch (status) {
			case 401: {
				$scope.message = "Você precisa ser autenticado!"
				break;
			}
			case 500: {
				$scope.message = "Erro!";
				break;
			}
			}
			console.log(data, status);
		});
	};
		

});

Os serviços em Angular que fazem as chamadas REstful implementadas. Esses serviços são usados em nosso controlador.
js/services.js


pessoasFormValidation.factory("serviceForm", function(config, $http) {

	var _getAllPessoas = function() {
		return $http
				.get("myapp/pessoa/all");
	};//http://localhost:8080/contex/myapp/pessoa/all
	
	var _getByIdPessoa = function(id) {
		return $http
				.get("myapp/pessoa/" + id);
	};
	

	var _savePessoa = function(pessoa) {
		return $http.post("myapp/pessoa/salvar", angular.toJson(pessoa));
	};

	var _updatePessoa = function(pessoa) {
		return $http.put("myapp/pessoa/" + pessoa.id, angular.toJson(pessoa));
	};

	var _deletePessoa = function(id) {
		return $http.delete("myapp/pessoa/" + id);
	};

	var _calculate = function(people) {

		var _nascimento = people.nascimento;
		var _dataCorrente = people.dataCorrente;			

		var _age = new Date(_dataCorrente).getFullYear()
				- new Date(_nascimento).getFullYear();
		
		return {
			age : _age,
		};
	};

	return {
		getAllPessoas : _getAllPessoas,
		getByIdPessoa :_getByIdPessoa,
		savePessoa : _savePessoa,
		updatePessoa : _updatePessoa,
		deletePessoa:_deletePessoa,
		calculate : _calculate
	};

});


Abaixo por fim será apresentado nosso formulário web, onde todos os métodos do controller são usados.

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" ng-app="appForm">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<script
	src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>


<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/directives.js"></script>
<script src="js/constants.js"></script>

<title>Insert title here</title>
</head>
<body ng-controller="ctrlPpessoasFormValidation">

	<form name="form">
		
		<h3 name="messag1e" ng-bind='message' ng-required="false"></h3>
	
	 	<table>
		<thead>
			<tr>
			    <th>Sel</th>
				<th>id</th>
				<th>Nome</th>
				<th>Email</th>
				<th>Data</th>
				<th>Data</th>
				<th>Idade</th>					
			</tr>
		</thead>
		<tbody>
			<tr ng-repeat="pes in listaPessoas">
			<td>			
			<input type="radio" ng-model="checkboxIdPessoa.id" ng-change="selectPessoa(pes)" ng-value="pes.id">
			</input></td>
			    <td>{{pes.id}}</td>
				<td>{{pes.nome}}</td>
				<td>{{pes.email}}</td>				
				<td>{{pes.nascimento}}</td>
				<td>{{pes.dataCorrente}}</td>
				<td>{{pes.idade}}</td>					
			</tr>
		</tbody>
	</table>	
	

&lt;build&gt;
		
	<p>
			Id: <input type="text" name="id" ng-model="pessoa.id" readonly="true" placeholder="Id" ng-required="false" />
			<div ng-show="form.id.$invalid">
				<span ng-show="form.id.$error.required">Identificar Id.</span>
				<span ng-show="form.id.$error.text">Erro preenchimento Id.</span>
			</div>
		</p>



		<p>
			Nome: <input type="text" name="nome" ng-model="pessoa.nome"	placeholder="Nome" ng-required="true" />
			<div ng-show="form.nome.$invalid">
				<span ng-show="form.nome.$error.required">Identificar Nome.</span>
				<span ng-show="form.nome.$error.text">Erro preenchimento Nome.</span>
			</div>
		</p>
		<p>
			Email: <input type="email" name="uEmail" ng-model="pessoa.email" placeholder="E-mail" ng-required="true" />
			<div ng-show="form.uEmail.$invalid">
				<span ng-show="form.uEmail.$error.required">Identificar Email.</span>
				 <span ng-show="form.uEmail.$error.email">Erro preenchimento Email.</span>
			</div>
		</p>
		
		
		
		<p>
			Nascimento: <input type="text" name="dataNasc" ng-model="pessoa.nascimento" placehoder="YYYY-MM-DD" ng-required="true" />
			<div ng-show="form.dataNasc.$invalid">
				<span ng-show="form.dataNasc.$error.required">Preencha a data nascimento.</span>
				 <span ng-show="form.dataNasc.$error.date">Data inválida.</span>
			</div>
		</p>
		
			<p>
			Data cor: <input type="text" name="dataCorrente" ng-model="pessoa.dataCorrente" placehoder="YYYY-MM-DD" ng-required="true" />
			<div ng-show="form.dataCorrente.$invalid">
				<span ng-show="form.dataCorrente.$error.required">Preencher data corrente.</span>
					 <span ng-show="form.dataCorrente.$error.date">Erro no preenchimento da data corrente.</span>
			</div>
		</p>
		
				

		<p>
			<h3>Calculo de Idade:</h3>
			<h3 name="ageP" ng-bind='pessoa.idade' ng-required="false"></h3>
			<p>{{idadePessoa.age}}</p>
			<div ng-show="form.ageP.$invalid">
				<span ng-show="form.ageP.$error.required">Data.</span>
					 <span ng-show="form.ageP.$error">Invalida idade.</span>
			</div>
		</p>


<p>form.$valid = {{form.$valid}}</p><br/>


<button ng-click="savePessoa(pessoa)" ng-disabled="form.$invalid">Salvar Pessoa</button>
<button ng-click="updatePessoa(pessoa)" ng-disabled="form.$invalid">Atualizar Pessoa</button>
<button ng-click="deletePessoa(pessoa)" ng-disabled="form.$invalid">Remover Pessoa</button><br/>


<button ng-click="calcular(pessoa)" ng-disabled="form.$invalid">Calcular Idade</button><br/>



	</form>


</body>
</html>

Bom é isso ai, uma aplicação bem simples mostrando a integração dom RestFul Jersey.

About the author

Clayton Casteli

Atua com desenvolvimento de software, J2EE, C/C++, IBM BPM. É entusiasta de novas tecnologias, principalmente open source. Formado em Engenharia da Computação pela PUCCAMP-SP, Pós-Graduado pela UNICAMP em Engenharia de Software com enfase em SOA e Pós-Graduado em Business Intelligence pelo IBTA.

Be Sociable, Share!

6 Responses so far.

  1. Tiago says:

    Olá obrigado pelo tutorial, poderia me tirar algumas dúvidas?

    "List<Pessoa> listP = Util.getInstance().getlPessoa();"

    o que seria esse trecho de código ?
    "List<Pessoa> listP " seria "List listP" ?

    e esse Utils ?? de que biblioteca seria ?? (não tem os imports pra ver)

    poderia disponibilizar os fontes completo do projeto. grato.

    • Tiago says:

      tem uns códigos estranhos la acho q foi o html da página.

      mas continuo com dúvida desse "Utils".

    • admin says:

      List listP na verdade isso e a forma de usar generics em java.

      Isso identifica uma lista que recebe instancias de Pessoas.

    • admin says:

      List listP na verdade isso e a forma de usar generics em java.

      Isso identifica uma lista que recebe instancias de Pessoas.

  2. Tiago says:

    me desculpe já entendi, obrigado pelo tutorial !

    • admin says:

      Boa tarde, Tiago.

      Que isso tranquilo. você esta certo os sinal <> foram convertidos...kkk

      O Util é só para gerar uma lista de pessoas fake. Na verdade nesse ponto você poderia usar JPA e plugar diretamente em um banco.

      Abraços,


Protected by WP Anti Spam