Alura > Cursos de Programação > Cursos de Java > Conteúdos de Java > Primeiras aulas do curso Java: trabalhando com lambdas, streams e Spring Framework

Java: trabalhando com lambdas, streams e Spring Framework

Um novo projeto utilizando o Spring Framework - Apresentação

Jacqueline: Olá! Boas-vindas ao curso de Spring Boot API. Sou a Jacqueline Oliveira, engenheira de software e instrutora na Alura.

Audiodescrição: Jacqueline é uma mulher de pele clara, cabelos longos e loiros e olhos escuros. Está com uma camiseta na cor azul-marinho. Ao fundo, uma parede clara com iluminação azul. À esquerda, uma prateleira com livros.

Iasmin: Oi, tudo bem? Eu sou a Iasmin Araújo, Scuba Team na Escola de Programação e também te desejo boas-vindas a mais um curso de Java!

Audiodescrição: Iasmin é uma mulher de pele clara, olhos verdes e cabelos longos na cor castanho-escuro. Está com uma camiseta preta, fone de ouvido branco e em uma cadeira gamer preta e branca. Ao fundo, uma parede lisa com a iluminação azul.

Pré-requisitos

Jacqueline: Para esse curso, é muito importante que você já tenha concluído a formação Java com Orientação a Objetos.

Isso porque, o objetivo desse curso é trazer aprofundamento em novos recursos da linguagem, essenciais no dia a dia da pessoa back-end.

O que você irá aprender

Iasmin: Nesse curso, criaremos um projeto utilizando Spring Boot.

Adicionaremos dependências no projeto, como o Jackson. E faremos o gerenciamento dessas dependências utilizando o Maven.

Vamos explorar as funções lambda e utilizar a API de streams do Java para fazer operações com coleções e manipular os dados de diversas formas.

Além disso, vamos relembrar alguns conceitos importantes, como interface, generics, API de datas e outras classes muito importantes no Java.

Jacqueline: Para isso, trabalharemos novamente com a Screen Match, uma aplicação de streaming de filmes e séries.

Atuaremos em uma aplicação linha de comando com foco nas séries. Assim, poderemos desenvolver melhor as coleções, considerando que uma série pode ter várias temporadas com vários episódios.

Iasmin: Por fim, teremos desafios no fim do curso para colocar em prática todo o aprendizado adquirido nas aulas.

Jacqueline: Além dos vídeos, atividades e desafios, você também tem acesso a outros recursos na plataforma, como o podcast, o Fórum e o canal no Discord.

Estamos ansiosas para começar. Vamos lá?

Um novo projeto utilizando o Spring Framework - Um novo projeto utilizando o Spring Framework

Jacqueline: Na formação de Java com Orientação a Objetos aprendemos fundamentos importantes, como buscar dados de uma API OMDb e trabalhamos essas informações e com coleções

Agora, nosso objetivo é continuar esse desenvolvimento, porém trabalhando com dados mais complexos.

Na formação, por exemplo, usamos os dados do filme Top Gun. Para as séries funciona da mesma forma, a diferença é que será mais trabalhoso.

Iasmin: Verdade, Jacque. Isso porque, além das informações gerais da série, também precisaremos trabalhar com as informações das temporadas e episódios.

Jacqueline: Ao escolhermos uma série, como Girlmore girls, e indicarmos na url a temporada, a aplicação já traz uma lista de episódios.

Durante o curso, trabalharemos com séries que possuem listas de temporadas e listas de episódios. Assim, vamos aumentando a complexidade do conteúdo.

O diferencial é que não criaremos o projeto com o Build System do IntelliJ. Usaremos frameworks, nesse caso o Spring e o Maven.

Criando o projeto com Spring

Iasmin: Como sabemos que chegaremos em um nível mais avançado, começamos com configurações de mesmo nível.

Jacqueline: Exatamente! O Spring é um framework muito utilizado por pessoas desenvolvedoras de Java no mercado.

Um framework é um conjunto de bibliotecas, ferramentas e convenções que facilitam o trabalho de desenvolvimento.

Isso porque abstraem acesso a banco de dados, tratamento de requisições HTTP, validação de dados, tudo para que possamos focar melhor no que é referente a regra de negócio.

Ao longo do curso perceberemos isso na prática. Começaremos com um projeto pequeno e em sequência acrescentaremos novos módulos do Spring para aumentar a complexidade.

Posteriormente, podemos pegar essa aplicação, que a princípio será de linha de comando, e transformá-la em aplicação web.

Isso se torna mais fácil quando já iniciamos com o framework, porque o Spring não é apenas para fazer API REST. Podemos fazer arquitetura de microservices, aplicação serverless, Batch. Há muito que se pode fazer com o Spring.

Iasmin: Começaremos fazendo um Spring sem web, é isso Jacque?

Jacqueline: Sim, essa é uma novidade. Todos conhecem o Spring web, aprenderemos agora o Spring sem web.

Para isso, no navegador, acessamos o site de inicialização Spring Initializr para criação de projetos Spring Boot. Nessa página, encontramos as configurações necessárias para iniciar o projeto de forma rápida.

Na página inicial, é preciso realizar algumas configurações para iniciar o projeto. Primeiro, escolhemos o tipo de gerenciador de dependências. Nesse caso, usaremos o Maven.

Em seguida, escolhemos a linguagem Java e escolhemos sempre a última versão.

Na época em que o vídeo foi gravado a última versão disponível era a 3.1.1.

Logo abaixo, encontramos os campos de preenchimento referentes aos metadados, ou seja, as informações do projeto. Preenchemos da seguinte forma:

Group: br.com.alura

Artifact: screenmatch

Name: screenmatch

Description: Primeiro projeto Spring sem web

Package name: br.com.alura.screenmatch

Packaging: Jar

Java: 17

Na lateral superior direita, encontramos o botão "Add Dependencies", mas não vamos adicionar nenhuma dependência agora, somente quando for necessário.

Após preencher essas informações, clicamos no botão "Generate", no canto inferior esquerdo. Em seguida, o Spring gera um arquivo compactado e realiza o download.

No nosso caso, foi gerado um arquivo chamado screenmatch.zip. O próximo passo é recortar o arquivo apertando "Ctrl + X". Em seguida, colaremos em uma pasta do computador chamada "Curso".

Em seguida, clicamos com o botão direito na pasta e depois em "Extrair Tudo". Feito isso, teremos a pasta com a estrutura de um projeto Maven.

Abrimos o IntelliJ e na barra de menu superior, clicamos em "File > Open" e selecionamos o arquivo baixado.

A princípio, esse projeto tem uma estrutura de pastas Source, Main, Java. Além disso, também encontramos a pasta principal com o nome completo da aplicação, uma parte de testes e o arquivo Pom.xml.

Vale lembrar que disponibilizaremos todo esse material. Com o tempo, tudo se tornará mais simples e familiar, pois o trabalho com Spring será semelhante.

ScreenmatchApplication.java

Observe que o SreenmatchApplication possui uma classe principal que tem o Public Static Void Main. Esse é o ponto de entrada da nossa aplicação. Ele tem um Spring Application.run que executará algo.

    public static void main(String[] args) {
        SpringApplication.run(ScreenmatchApplication.class, args);
    }

Podemos executar essa aplicação de várias formas, como clicando na seta verde ao lado esquerdo de Public Static Void Main e na barra de menu superior.

Optamos pela primeira opção, então clicamos no ícone de play na linha 9 e depois em "Run" para descobrirmos o que acontece ao rodar um projeto spring do zero.

No terminal, notamos que é exibido o Spring Boot, a versão, um log informando que a aplicação foi iniciada e o tempo de 7 segundos.

Como não temos nada implementado, tivemos como retorno uma mensagem de "process finish with code zero", ou seja, terminou com o código, isso indica que está tudo certo. Não há nada para ser feito, mas o projeto já está no ar, pronto para ser trabalhado.

Dissemos anteriormente que faremos uma aplicação de linha de comando. Para isso, na classe principal public class ScreenmatchApplication, precisamos informar que ela implementa a interface de linha de comando.

Portanto, escrevemos implements CommandLineRunner. Essa interface permitirá realizar algumas chamadas no método principal, semelhante ao que fazemos na formação de Orientação a Objetos, na qual o método main realizava várias ações.

Quando uma interface é implementada, temos um contrato. Portanto, preciso implementar os métodos ainda não implementados, que nesse caso, é o run.

Quando o método run é implementado, o que o código indica que quando o public static void main chamar o SpringApplication.run, ele invocará esse método run que estamos implementando.

**Iasmin: ** Esse método run vai atuar como um método main, pois faremos tudo que seria feito em um main comum, como na formação anterior.

Jacqueline: Exatamente! Então, como primeiro passo, normalmente passaríamos um "Hello, World!". Nesse caso, faremos isso, porém faremos um System.out.println informando Primeiro projeto Spring sem web, este log será exibido no terminal.

@SpringBootApplication
public class ScreenmatchApplication implements CommandLineRunner {

    public static void main(String[] args) {
        SpringApplication.run(ScreenmatchApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        System.out.println("Primeiro projeto Spring sem web.");
    }
}

Executamos o código para verificar se está tudo funcionando corretamente. Repare que na lateral inferior direita é exibido no terminal "Primeiro projeto Spring sem web.".

Assim damos inicio ao nosso primeiro projeto Spring sem web!

Iasmin: Isso mesmo, Jacque! É interessante lembrar que no Spring Initializer, nós apenas clicamos em alguns botões e já tivemos um projeto bastante configurado, praticamente pronto para rodar.

Em seguida, para fazer o "Hello, World!", foi apenas necessário sobrescrever o método run. É bem simples e tranquilo usar esses frameworks.

Jacqueline: O passo seguinte é começar realmente a modelar a aplicação e implementar a proposta de consumir séries, trabalhar com listas e coleções de temporadas, episódios e aumentar o escopo do nosso projeto.

Iasmin: Até lá!

Um novo projeto utilizando o Spring Framework - Consumindo dados de séries

Jacqueline: Iniciamos o projeto Spring. No entanto, precisamos consumir a API desejada para buscar os dados retornados em um formato JSON, similar ao que realizamos na formação anterior, mas com algumas particularidades.

Criando o pacote de serviços

Jacqueline: Como vamos consumir a API e trazer os dados, ou seja, um serviço, criaremos então um pacote de serviços chamado service.

Para isso, no arquivo br.com.alura.screenmatch, clicamos com o botão direito e depois em "New > Package". Nomeamos de service.

Feito isso, criaremos uma classe que poderá consumir essa API e outras. Em service, clicamos com o botão direito e depois em "New > Java Class". Nomeamos de ConsumoApi.

Agora, precisamos usar métodos para fazer requisição e resposta.

Iasmin: Isso mesmo, Jacque! Da mesma forma que acessamos o navegador e digitamos a url, que é a requisição, agora precisamos fazer uma requisição e pegar a resposta, ou seja, o response, para trabalhá-lo.

Jacqueline: Então, na classe ConsumoApi, criamos um método público utilizando public String e o nomeamos de obterDados.

Para obter esses dados, precisamos de um endereço. Sendo assim, nos parênteses passamos o parâmetro String endereco.

Como este código já foi mostrado anteriormente, disponibilizaremos sua versão completa nos materiais do curso.

Para otimizar tempo, copiamos e colamos o código abaixo:

package br.com.alura.screenmatch.service;

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class ConsumoApi {

    public String obterDados(String endereco) {
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(endereco))
                .build();
        HttpResponse<String> response = null;
        try {
            response = client
                    .send(request, HttpResponse.BodyHandlers.ofString());
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        String json = response.body();
        return json;
    }
}

Jacqueline: Temos um HttpClient, que pode ser considerado o cliente e o HttpRequest, onde criamos uma URI para especificar para qual endereço faremos a requisição.

Depois, tentamos receber uma resposta. Para isso, o cliente enviará a requisição e receberemos essa resposta. Assim, o retorno do método devolve a String json, que é o corpo da resposta, o response.body().

Também temos os trycatch, o tratamento das exceções, porque pode ocorrer algum erro ao passar um endereço errado, por exemplo.

Consumindo dados de séries

Jacqueline: Agora, consumiremos a API. Para isso, usaremos a classe principal.

Iasmin: A intenção será acessar o método run e chamar essa classe ConsumoAPI, certo, Jacque? Isso acaba tornando nosso código muito mais modularizado, de fácil manutenção e mais legível também.

Jacqueline: Exatamente. Então, começamos apagando a linha abaixo de public void run(). No lugar, escrevemosConsumoAPI consumoApi = new ConsumoApi(). Instanciamos a classe.

Feito isso, na linha abaixo, criamos uma variável com var json, que já é conhecido por nossa inferência de tipo.

Iasmin: Inclusive, como temos vários ConsumoApi repetidos, podemos utilizar o var na linha de código acima, né?

Jacqueline: Verdade, Iasmin! Então, na linha acima, apagamos o ConsumoApi e passamos var. Assim a ferramenta reconhece que pelo new estamos instanciando uma variável do tipo consumoApi.

Feito isso, voltamos para o json, que será igual à consumoApi.obterDados(). Assim, será devolvido uma string que estamos passando na variável json.

Nos parênteses, precisamos passar o endereço da série que queremos buscar.

https://www.omdbapi.com/?t=gilmore+girls&apikey=6585022c

Lembrando que, para se cadastrar no OMDB, é importante ter a sua própria API Key. Estamos utilizando uma chave gratuita que expira ao consultar muitos dados.

Copiamos esse endereço e passamos nos parênteses. Em sequência, queremos imprimir os dados adquiridos pelo json, então escrevemos System.out.println(json).

//Código omitido

@Override
public void run(String... args) throws Exception {
    var consumoApi = new ConsumoApi();
    var json = consumoApi.obterDados("https://www.omdbapi.com/?t=gilmore+girls&apikey=6585022c");
    System.out.println(json);

}

Agora, verificaremos se o código trará os dados do Gilmore Girls para o meu terminal. Para isso executamos a aplicação, dessa vez, clicaremos no botão indicado pelo ícone de play localizado na barra de menu superior direita.

Analisando o terminal encontramos todas as informações referentes a primeira temporada, como os episódios, ano de lançamento, avaliação.

Comentamos anteriormente que ter uma classe de serviço específica é bacana. Isso porque, agora, por exemplo, podemos pegar o json e chamar para consumir dados de um lugar completamente aleatório.

Vamos testar! No fim do código passamos json igual à consupoApi.obterDados() e passar como parâmetro uma API que devolverá uma imagem de café. Para isso, colamos a url referente ao café e na linha abaixo escrevemos System.out.println(json).

    @Override
    public void run(String... args) throws Exception {
        var consumoApi = new ConsumoApi();
        var json = consumoApi.obterDados("https://www.omdbapi.com/?t=gilmore+girls&apikey=6585022c");
//		System.out.println(json);
//		json = consumoApi.obterDados("https://coffee.alexflipnote.dev/random.json");
        System.out.println(json);
}
}

Ao executar o código, visualizamos no terminal tanto as informações da série quanto a imagem do café, devolvida por um json. Ao clicar na imagem, ela abre no navegador.

O legal de usar as boas práticas e ter uma classe específica para consumir uma API, é que não importa o tipo da API. A classe estará pronta, portanto, independente do tipo de API ela conseguirá realizar o mesmo trabalho, ou seja, buscar uma informação e devolver o json.

É bem interessante pensarmos nesse tipo de boa prática de separar responsabilidades, deixá-la consumir a API em uma classe separada.

No vídeo seguinte continuaremos trazendo melhorias para a aplicação. Até lá!

Sobre o curso Java: trabalhando com lambdas, streams e Spring Framework

O curso Java: trabalhando com lambdas, streams e Spring Framework possui 326 minutos de vídeos, em um total de 71 atividades. Gostou? Conheça nossos outros cursos de Java em Programação, ou leia nossos artigos de Programação.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda Java acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas