Engenharia de Telecomunicações Prof.
Emerson Ribeiro de Mello
STD29006 – Sistemas Distribuídos mello@[Link]
Laboratório 5: Serviços Web REST em Java
03/11/2025
Conteúdo
1 Criando estrutura do projeto Java Gradle com o framework Spring 1
2 Primeiro exemplo: Uso do verbo GET HTTP 2
2.1 Crie os pacotes e as classes Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2.2 Como executar o projeto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.3 Como consumir o serviço usando o cURL . . . . . . . . . . . . . . . . . . . . . . . . . 3
3 Segundo exemplo: Verbos GET, POST, PUT e DELETE 4
3.1 Crie os pacotes e as classes Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
3.2 Como consumir o serviço usando o cURL . . . . . . . . . . . . . . . . . . . . . . . . . 8
4 Aplicação Java para consumir serviço REST 8
5 Documentação de API com OpenAPI 3 11
1 Criando estrutura do projeto Java Gradle com o framework Spring
Java possui diversos frameworks e APIs que possibilitam o desenvolvimento de Serviços Web REST-
ful, como a API Java para RESTful Web Services (JAX-RS) e o framework Spring1 . Nesse laboratório
faremos uso do Spring Boot para criar o projeto. Siga os passos abaixo (também é possível fazer
pelo VSCode + extensão Spring Boot Extension Pack ou IntelliJ Ultimate):
1. Acesse [Link]
2. Marque as seguintes opções:
• Project: Gradle - Groovy
• Language: Java
• Spring Boot: 3.5.7
3. Em project metadata preencha com os seguintes valores:
• Group: [Link]
• Artifact: labrest
• Description: Laboratório RESTful com Java
• Packing: Jar
4. Em dependencies clique no botão Add dependencies
• Adicione Spring Web
1
[Link]
IFSC – C AMPUS S ÃO J OSÉ Página 1
5. Clique no botão Generate para baixar o arquivo ZIP contendo o projeto
6. Descompacte o ZIP, pelo terminal entre neste diretório e atualize a versão do Gradle Wrapper:
cd labrest
gradle wrapper --gradle-version latest
7. Por fim, abra esse projeto na IDE IntelliJ ou com o Visual Studio Code.
O Spring Boot possui diversas diretrizes de configuração2 as quais são indicadas no arquivo
src/main/resources/[Link]. No exemplo abaixo são colocadas algumas confi-
gurações para diminuir o número de mensagens de LOG que aparecem ao executar a aplicação.
# Disabling Spring banner
[Link]-mode=off
# TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF
[Link]=ERROR
[Link]=ERROR
# Nível de log para as minhas classes
# TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF
[Link]=WARN
2 Primeiro exemplo: Uso do verbo GET HTTP
Na Tabela 1 é apresentada a API desse primeiro exemplo que teve como base o guia disponível
em [Link] São descritos os verbos HTTP que poderão ser usados
sobre cada recurso, bem como a informação que será retornada.
Tabela 1: API do Serviço Web de Saudação
Método Recurso Resposta
GET /saudacao Documento JSON {"id":1,"nome":"Olá Mundo"}
/saudacao?nome=SeuNome Documento JSON {"id":2,"nome":"Olá SeuNome"}
2.1 Crie os pacotes e as classes Java
Crie os pacotes entities e controller e as classes [Link] e [Link]
para ficar de acordo com a estrutura apresentada abaixo:
.
`-- engtelecom
`-- std
`-- labrest
|-- [Link]
|-- controller
| `-- [Link]
`-- entities
`-- [Link]
2
[Link]
IFSC – C AMPUS S ÃO J OSÉ Página 2
Na Listagem 1 é apresentado o conteúdo da classe Record 3 [Link]. Sempre que o
recurso /saudacao for consumido com o método GET, será criada uma instância dessa classe e os
atributos da mesma serão convertidos para um documento JSON e retornados ao solicitante.
package [Link];
public record Saudacao(long id, String nome){}
Na Listagem 2 é apresentado o conteúdo do código da classe responsável por processar os
pedidos e instanciar objetos da classe [Link]. Como apresentado na Tabela 1, o recurso
/saudacao tem um parâmetro nome que é opcional.
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
@RestController
public class SaudacaoController {
private static final String MENSAGEM = "Olá %s";
private final AtomicLong contador = new AtomicLong();
@GetMapping("/saudacao")
public Saudacao saudacao(@RequestParam(value = "nome", defaultValue = "mundo") String nome){
return new Saudacao([Link](), [Link](MENSAGEM, nome));
}
}
2.2 Como executar o projeto
Com as classes finalizadas, você poderá executar o projeto usando o gradle. Execute a tarefa do
gradle (task) chamada bootRun que, no meu da IDE, estará dentro da categoria application. Se
optar por executar no terminal:
./gradlew bootRun
Ao executar, será instanciado um processo que ficará aceitando conexões HTTP na porta 8080.
2.3 Como consumir o serviço usando o cURL
Para consumir o serviço REST implementado nessa seção você precisará de uma aplicação capaz
de realizar requisições HTTP. O curl é um aplicativo de linha de comando presente no Linux que
poderia ser usado para tal.
# Obtendo a mensagem padrão Olá mundo
curl [Link]
# Obtendo a mensagem Olá Joao
curl -L -X GET '[Link]
3
É um tipo especial de classe ideal quando deseja-se criar objetos imutáveis e usados para transferência de dados e
evitando assim a ter que recorrer a soluções com o Projeto Lombok para evitar ter que criar métodos getters, construtores,
etc. Veja mais em [Link]
IFSC – C AMPUS S ÃO J OSÉ Página 3
3 Segundo exemplo: Verbos GET, POST, PUT e DELETE
Esse exemplo tem como único objetivo demonstrar como usar os verbos HTTP GET, POST, PUT
e DELETE, bem como os códigos de estado do HTTP na resposta. O exemplo consiste de uma
simples agenda de contatos armazenada em memória.
Tabela 2: API do Serviço Web Agenda de Contatos
Verbo Recurso Corpo do pedido Corpo da reposta HTTP Status
GET /pessoas – Documento JSON com id, nome 200
e email de todas pessoas
/pessoas/{id} – Documento JSON com id, nome 200 ou 404
e email do id informado
POST /pessoas Documento JSON com Documento JSON com id, nome 201
nome e email do novo e email
contato
PUT /pessoas Documento JSON com no- Documento JSON com id, nome 200 or 404
vos valores para nome e e email
email
DELETE /pessoas/{id} – – 204 or 404
3.1 Crie os pacotes e as classes Java
Crie pacotes e classes Java para ficar de acordo com a estrutura apresentada abaixo:
.
`-- engtelecom
`-- std
`-- labrest
|-- [Link]
|-- controller
| |-- [Link]
| `-- [Link]
|-- entities
| |-- [Link]
| `-- [Link]
|-- exceptions
| `-- [Link]
`-- service
`-- [Link]
Na Listagem 3 é apresentado o código da classe [Link]. Trata-se de um Plain Old Java
Object (POJO)4 para representar uma pessoa na agenda de contatos. É obrigatório ter um método
construtor padrão (método sem parâmetros).
package [Link];
public class Pessoa {
private long id;
private String nome;
private String email;
public Pessoa() { }
4
Você pode fazer uso do projeto Lombok para gerar o POJO de maneira mais simples. Veja [Link]
setup/gradle
IFSC – C AMPUS S ÃO J OSÉ Página 4
public Pessoa(String nome, String email) {
[Link] = nome;
[Link] = email;
}
public long getId() {return id;}
public void setId(long id) {[Link] = id;}
public String getNome() {return nome;}
public String getEmail() {return email;}
public void setNome(String nome) {[Link] = nome;}
public void setEmail(String email) {[Link] = email;}
}
Na Listagem 4 é apresentado o código de uma classe que será usada caso o id da pessoa,
informado pelo usuário, não estiver armazenado na memória.
package [Link];
public class PessoaNaoEncontradaException extends RuntimeException {
public PessoaNaoEncontradaException(long id) {
super("Não foi possível encontrar pessoa com o id: " + id);
}
}
Na Listagem 5 é apresentado o conteúdo da classe PessoaService que neste exemplo repre-
senta um banco de dados, em memória, de objetos do tipo Pessoa.
Listagem 5: [Link]
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
/**
* PessoaService é uma classe que simula um banco de dados.
*
* A anotação @Component indica que a classe PessoaService é um componente do
* Spring. Isso significa que o Spring irá gerenciar as instâncias dessa classe
* e irá injetá-las onde for necessário.
*
* Classes anotadas com @Component são chamadas de beans. E são singleton por
* padrão, ou seja, o Spring irá criar apenas uma instância dessa classe e irá
* compartilhá-la entre todos os componentes que a utilizarem.
*
* [Link]
*
*/
@Component
public class PessoaService {
// criando uma lista para simular um banco de dados em memória
private List<Pessoa> pessoas;
// criando um contador para gerar ids. O contador é estático para que seja
// compartilhado entre todas as instâncias da classe PessoaService
IFSC – C AMPUS S ÃO J OSÉ Página 5
// O contador é do tipo AtomicLong para que as operações de incremento e
// decremento sejam atômicas
private static AtomicLong contador = new AtomicLong();
public PessoaService() {
pessoas = new ArrayList<>();
// adicionando algumas pessoas para facilitar os testes
[Link](new Pessoa("João", "joao@[Link]"));
[Link](new Pessoa("Maria", "maria@[Link]"));
[Link](new Pessoa("Juca", "juca@[Link]"));
}
public Pessoa cadastrar(Pessoa pessoa) {
// gerando um id para a pessoa e ignorando o id enviado
[Link]([Link]());
[Link](pessoa);
return pessoa;
}
public List<Pessoa> buscarTodos() {
return pessoas;
}
public Pessoa buscarPorId(Long id) {
return [Link]().filter(p -> [Link]().equals(id)).findFirst().orElse(null);
}
public Pessoa atualizar(Pessoa pessoa) {
Pessoa p = buscarPorId([Link]());
if (p != null) {
[Link]([Link]());
[Link]([Link]());
}
return p;
}
public boolean excluir(Long id) {
return [Link](p -> [Link]().equals(id));
}
}
Na Listagem 6 é apresentado o conteúdo do código da classe responsável por processar os
pedidos a API REST e interagir com o banco de dados de pessoas. Cabe salientar que as práticas
nesse projeto não são adequadas em um ambiente de produção, pois seria recomendado armazenar
a agenda em um banco de dados em memória não volátil.
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
IFSC – C AMPUS S ÃO J OSÉ Página 6
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
@RestController
// Mapeia as URLs /pessoas e /pessoas/ para esse controller
// Se desejar usar versionamento de API, basta adicionar a versão. Ex:
// /v1/pessoas
@RequestMapping({ "/pessoas", "/pessoas/" })
public class AgendaController {
@Autowired // injeta uma instância de PessoaService que está anotada com @Component
private PessoaService pessoaService;
@GetMapping
public List<Pessoa> obterTodasPessoas() {
return [Link]();
}
@GetMapping("/{id}")
@ResponseStatus([Link])
public Pessoa obterPessoa(@PathVariable long id) {
Pessoa p = [Link](id);
if (p != null) {
return p;
}
throw new PessoaNaoEncontradaException(id);
}
@PostMapping
@ResponseStatus([Link])
public Pessoa adicionarPessoa(@RequestBody Pessoa p) {
return [Link](p);
}
@PutMapping
@ResponseStatus([Link])
public Pessoa atualizarPessoa(@RequestBody Pessoa pessoa) {
Pessoa p = [Link](pessoa);
if (p != null) {
return p;
}
throw new PessoaNaoEncontradaException([Link]());
}
@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void excluirPessoa(@PathVariable long id) {
if () {
throw new PessoaNaoEncontradaException(id);
}
}
@ControllerAdvice
class PessoaNaoEncontrada {
@ResponseBody
@ExceptionHandler([Link])
@ResponseStatus(HttpStatus.NOT_FOUND)
IFSC – C AMPUS S ÃO J OSÉ Página 7
String pessoaNaoEncontrada(PessoaNaoEncontradaException p) {
return [Link]();
}
}
}
3.2 Como consumir o serviço usando o cURL
Para consumir o serviço REST implementado nessa seção você precisará de uma aplicação capaz
de realizar requisições HTTP. O curl é um aplicativo de linha de comando presente no Linux que
poderia ser usado para tal. Porém, para serviços mais complexos talvez fosse interessante usar
ferramentas mais completas, como o Bruno5 (software livre), o Postman6 , Insomnia7 ou HTTPie8 .
Na listagem abaixo é apresentado exemplos com o curl.
# Obtendo a lista com todos os contatos
curl -L -X GET '[Link]
# Adicionando um novo contato
curl -L -X POST '[Link] \
-H 'Content-Type: application/json' \
--data-raw '{
"nome" : "Juca",
"email": "juca@[Link]"
}'
# Obtendo detalhes de um único contato com o id = 1
curl -L -X GET '[Link]
# Alterando o email do contato com o id = 1
curl -L -X PUT '[Link] \
-H 'Content-Type: application/json' \
--data-raw '{
"nome" : "Juca",
"email": "novojuca@[Link]"
}'
# Excluindo o contato com o id = 1
curl -L -X DELETE '[Link]
4 Aplicação Java para consumir serviço REST
Em Java existem diversos frameworks e bibliotecas para desenvolver ou consumir serviços REST.
Nessa seção é apresentado um exemplo usando o OkHttp9 , que é apenas um cliente HTTP em Java
e que usaremos para consumir o serviço REST desenvolvido na Seção 3.
Crie um novo projeto Java com o gradle e deixe o conteúdo das seções plugins e dependencies,
do arquivo [Link], igual ao quadro abaixo:
plugins {
id 'application'
}
5
[Link]
6
[Link]
7
[Link]
8
[Link]
9
[Link]
IFSC – C AMPUS S ÃO J OSÉ Página 8
repositories {
mavenCentral()
}
dependencies {
// Cliente HTTP para Java
// [Link]
implementation '[Link].okhttp3:okhttp:4.12.0'
// Para converter JSON em objetos Java e vice-versa
// [Link]
implementation '[Link]:gson:2.11.0'
// Para gerar dados aleatórios - [Link]
// [Link]
implementation '[Link]:datafaker:2.3.0'
// Deixar as demais linhas já existentes nessa seção
}
Crie um classe POJO (ou record) para representar uma Pessoa. Essa classe deve ter os se-
guintes atributos: Long id, String nome, String email.
package [Link];
public record Pessoa(Long id, String nome, String email) {}
Por fim, crie uma classe para fazer requisições GET e POST.
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
public class App {
private OkHttpClient client = new OkHttpClient();
private final String HOST = "[Link]
private final MediaType MEDIA_TYPE = [Link]("application/json");
public void listarTodas() throws Exception {
// Padrao de projeto Builder
// [Link]
// url = [Link]
HttpUrl url = [Link](HOST).newBuilder()
.addPathSegment("pessoas")
.build();
Request request = new [Link]()
.url(url)
.get()
.build();
String response = [Link](request).execute().body().string();
IFSC – C AMPUS S ÃO J OSÉ Página 9
[Link](response);
}
public void cadastrarPessoa(Pessoa p) {
HttpUrl url = [Link](HOST).newBuilder()
.addPathSegment("pessoas")
.build();
RequestBody body = [Link](new Gson().toJson(p), MEDIA_TYPE);
Request request = new [Link]()
.url(url)
.post(body)
.build();
try (Response response = [Link](request).execute()) {
if ([Link]()) {
[Link]("Pessoa cadastrada com sucesso!");
} else {
[Link]("Erro ao cadastrar pessoa!");
}
} catch (Exception e) {
[Link]("Erro ao cadastrar pessoa!");
}
}
public void listarDadosDeUmaPessoa(Long id) throws Exception {
// url = [Link]
HttpUrl url = [Link](HOST).newBuilder()
.addPathSegment("pessoas")
.addPathSegment([Link]())
.build();
Request request = new [Link]()
.url(url)
.get()
.build();
String response = [Link](request).execute().body().string();
[Link](response);
}
public static void main(String[] args) throws Exception {
var app = new App();
var faker = new Faker();// classe que gera dados aleatórios
[Link]();
var nome = [Link]().firstName();
var email = [Link]().emailAddress();
[Link](new Pessoa(null, nome, email));
[Link]();
[Link](1L);
}
}
IFSC – C AMPUS S ÃO J OSÉ Página 10
5 Documentação de API com OpenAPI 3
A OpenAPI ([Link] é uma especificação que define uma linguagem padrão para
especificar APIs HTTP (APIs REST). A especificação da API pode ser escrita em JSON ou YAML. A
especificação OpenAPI é usada por diversas ferramentas para gerar código cliente e servidor, bem
como para gerar documentação interativa da API (veja um exemplo em [Link]
Em [Link] encontrar um tutorial sobre a especificação OpenAPI.
A biblioteca springdoc-openapi ([Link] é uma implementação da especificação
OpenAPI para o framework Spring. Essa biblioteca pode ser usada para gerar a documentação
da API REST desenvolvida nesse laboratório. Para isso, basta adicionar a dependência no arquivo
[Link] do projeto:
// [Link]
implementation '[Link]:springdoc-openapi-starter-webmvc-ui:2.8.14'
Após adicionar a dependência, acesse a URL [Link] para visuali-
zar a documentação da API REST desenvolvida nesse laboratório.
A documentação é gerada automaticamente a partir dos métodos anotados com @GetMapping,
@PostMapping, etc. Caso queira baixar o arquivo JSON com a especificação da API, acesse a URL
[Link] e caso queira baixar o arquivo YAML, acesse a URL [Link]
8080/v3/[Link].
Referências
1. [Link]
2. [Link]
3. [Link]
4. [Link]
5. [Link]
6. [Link]
7. [Link]
8. [Link]
cb Documento licenciado sob Creative Commons “Atribuição 4.0 Internacional”.
IFSC – C AMPUS S ÃO J OSÉ Página 11