Pular para o conteúdo

Atividade 09: HTTP e Comunicação de Dados

Na Atividade 08 você evoluiu a API de produtos para persistir os dados com Spring Data JPA e banco H2, expondo endpoints como POST /produtos, GET /produtos e GET /produtos/{id}.

Nesta atividade, vamos usar essa mesma API para explorar, na prática, os conceitos dos Tópicos 11 (Protocolo HTTP) e 12 (Comunicação de Dados): representações de um recurso, cabeçalhos, status codes, cookies, cache, serialização/desserialização e Object Mapping com o Jackson.

A atividade tem duas partes: Parte A com exercícios teóricos e Parte B com um exercício de implementação sobre a API da Atividade 08.


Assinale a alternativa correta em cada item.

  1. Qual método HTTP é seguro e idempotente?

    • a) POST
    • b) PUT
    • c) GET
    • d) PATCH
  2. Sobre PUT e PATCH, é correto afirmar que:

    • a) ambos substituem o recurso inteiro;
    • b) PUT substitui o recurso por completo e PATCH altera parte dele;
    • c) PUT altera parte do recurso e PATCH substitui por completo;
    • d) ambos são idempotentes e seguros.
  3. Qual método normalmente não é idempotente?

    • a) GET
    • b) POST
    • c) DELETE
    • d) HEAD

Para cada situação, indique o código de status HTTP mais adequado (200, 201, 204, 400, 401, 403, 404 ou 500):

  1. Um produto foi criado com sucesso por meio de um POST.
  2. Um recurso foi removido com sucesso e não há corpo na resposta.
  3. O cliente enviou um JSON com um campo obrigatório ausente.
  4. A requisição não trouxe um token de autenticação válido.
  5. O usuário está autenticado, mas não tem permissão para acessar a rota.
  6. O GET /produtos/{id} foi chamado com um id que não existe.
  7. Ocorreu um erro inesperado no servidor durante o processamento.

Explique, com suas palavras, a diferença entre os cabeçalhos Content-Type e Accept. Dê um exemplo de requisição em que os dois aparecem com valores diferentes e justifique.

Marque V ou F e justifique as falsas.

  1. ( ) No JSON, as chaves são sempre strings entre aspas duplas.
  2. ( ) O JSON possui um tipo de dado nativo para datas.
  3. ( ) Um vetor em JSON é delimitado por [ ].
  4. ( ) O JSON permite funções como valor.
  5. ( ) null, true e números são tipos válidos em JSON.

Os trechos abaixo não são JSON válidos. Aponte o erro de cada um e escreva a versão corrigida.

{ 'nome': 'Mouse Gamer', 'preco': 149.90 }
{ "nome": "Mouse Gamer", "categorias": ["periféricos", "acessórios", ] }
{ "nome": "Mouse Gamer" "preco": 149.90 }

O HTTP é considerado um protocolo sem estado (stateless). Explique o que isso significa e descreva como cookies e sessões permitem que uma aplicação “lembre” do estado do cliente entre requisições. Cite o papel dos cabeçalhos Set-Cookie e Cookie.

Descreva o funcionamento do cache HTTP com ETag. Em sua explicação, inclua:

  • o papel do ETag na resposta;
  • o cabeçalho If-None-Match na requisição seguinte;
  • por que o servidor pode responder 304 Not Modified;
  • a vantagem desse mecanismo em termos de banda e latência.

Exercício A8 - Discursiva (serialização e Object Mapping)

Seção intitulada “Exercício A8 - Discursiva (serialização e Object Mapping)”

Explique a diferença entre serialização e desserialização e o que é Object Mapping. Dê um exemplo de fluxo em que um objeto Java é convertido em JSON e outro em que um JSON recebido vira um objeto Java.

Pesquise e produza um pequeno resumo (meia página cada) sobre:

  1. JSON, XML e YAML: características, vantagens e um cenário de uso típico para cada um.
  2. JSON Schema e XSD: o que são e para que servem.
  3. Atributos de cookie HttpOnly, Secure e SameSite: o que cada um protege.

Exercício A10 - Associação (anotações Jackson)

Seção intitulada “Exercício A10 - Associação (anotações Jackson)”

Relacione cada anotação do Jackson à sua finalidade:

Anotação Finalidade
@JsonProperty ( ) Oculta um campo da serialização
@JsonIgnore ( ) Define o formato de datas/números
@JsonFormat ( ) Renomeia a chave usada no JSON
@JsonInclude ( ) Controla a inclusão de campos nulos/vazios

Nesta parte, você deve alterar a API de produtos persistida na Atividade 08. Mantenha a persistência com H2 e a estrutura com entidade, repositório e controller.

Exercício B1 - Um recurso, várias representações

Seção intitulada “Exercício B1 - Um recurso, várias representações”

Faça a API responder o mesmo recurso em formatos diferentes, conforme o cabeçalho Accept.

  • Crie um endpoint GET /produtos/{id}/resumo que devolva um texto (text/plain), por exemplo:

    Produto: Mouse Gamer - preço: R$ 149,90
  • Faça o endpoint GET /produtos/{id} responder em application/json e application/xml usando produces.

  • Adicione a dependência jackson-dataformat-xml ao projeto.

  • Crie um endpoint GET /produtos/{id}/html que devolva uma página HTML simples com os dados do produto (text/html).

  • Garanta que o cabeçalho Content-Type da resposta corresponda ao formato retornado.

@GetMapping(value = "/{id}", produces = {
MediaType.APPLICATION_JSON_VALUE,
MediaType.APPLICATION_XML_VALUE })
public Produto buscar(@PathVariable UUID id) {
return produtoRepository.findById(id).get();
}

Explore como o Jackson transforma os objetos da sua API em JSON.

  • Adicione à entidade Produto os campos: categoria (String), dataCadastro (LocalDate) e promocao (Boolean).
  • Deixe promocao como null em alguns registros e use @JsonInclude(JsonInclude.Include.NON_NULL) para que o campo não apareça no JSON quando nulo.
  • Use @JsonFormat para padronizar dataCadastro (ex.: yyyy-MM-dd).
  • Renomeie um campo no JSON com @JsonProperty (ex.: preco → price).
  • Use @JsonIgnore em um campo interno e comprove que ele não aparece na resposta.
  • Salve a resposta JSON antes e depois das anotações e explique o efeito de cada uma.

Exercício B3 - Inspecionando requisições no Postman/Insomnia

Seção intitulada “Exercício B3 - Inspecionando requisições no Postman/Insomnia”

Usando o Postman ou o Insomnia, monte e analise as requisições da API.

  • Para cada endpoint dos exercícios anteriores, monte uma requisição na ferramenta.
  • Altere o cabeçalho Accept (application/json e application/xml) e observe as respostas.
  • Envie um GET /produtos/{id} com um id inexistente e registre o status code.
  • Envie um POST /produtos com corpo inválido (ex.: sem nome) e registre o status.
  • Registre, para cada requisição:
    • Método e URL;
    • Cabeçalhos de requisição (Accept, Content-Type);
    • Status code da resposta;
    • Cabeçalho Content-Type da resposta;
    • Um trecho do corpo da resposta.
  • Crie um endpoint que defina um cookie com o cabeçalho Set-Cookie (ex.: ultimoProduto=...).
  • Crie um endpoint que responda com Cache-Control e ETag, permitindo a validação condicional (If-None-Match → 304 Not Modified).
  • Envie um POST /produtos com Content-Type: application/xml e um corpo XML, fazendo o Spring desserializar o XML em um objeto.
  • Documente, com prints do Postman/Insomnia, o comportamento observado em cada caso.

  • Parte A: respostas dos exercícios teóricos.
  • Parte B: código-fonte da API atualizada e prints das requisições/respostas no Postman/Insomnia.
  • Uma pequena tabela relacionando endpoint, método, status e Content-Type observados.