Olá. Quebrei bastante a cabeça para dividir este código em classes e fazê-lo funcionar. Ainda tenho dificuldades com as exceções, achei mais fácil criar exceções para alguns problemas específicos, mas sei que no mundo real terei que lidar com com estas do Java. Se alguém tiver algum feedback, principalmente com relação à divisão das classes, porque eu não estou seguro da legibilidade do modo como eu fiz.
Criei a classe ConectaOmdb com um método que faz a conexão com a API e retorna o Json:
package br.com.alura.screenmatch.api;
import br.com.alura.screenmatch.excecao.ErroTituloNaoEncontradoException;
import java.io.IOException;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
public class ConectaOmdb {
public String buscaOmdb(String filme) {
String chave = "ba604588";
URI endereco = URI.create("https://www.omdbapi.com/?t=" +
URLEncoder.encode(filme, StandardCharsets.UTF_8) + "&apikey=" + chave);
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(endereco)
.build();
try {
HttpResponse<String> response = client
.send(request, HttpResponse.BodyHandlers.ofString());
return response.body();
} catch (IOException | InterruptedException | IllegalArgumentException e) {
throw new ErroTituloNaoEncontradoException("Não foi possível encontrar o filme digitado.");
}
}
}
Tem também a classe ManipulaJson, com um método que transforma o Json criado pelo método buscaOmdb() em uma classe Java e outro que gera e salva a lista em Json. Esta foi a classe que me deixou mais desconfortável. Coloquei os métodos nesta classe por eles compartilharem o Gson e achei mais cômodo deixá-los na mesma classe, mas não sei se foi a opção certa.
package br.com.alura.screenmatch.api;
import br.com.alura.screenmatch.excecao.ErroSalvarJsonException;
import br.com.alura.screenmatch.modelo.Titulo;
import br.com.alura.screenmatch.modelo.TituloOmdb;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
public class ManipulaJson {
Gson gson = new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
.setPrettyPrinting()
.create();
public Titulo converteTitulo(String filme) {
ConectaOmdb busca = new ConectaOmdb();
TituloOmdb meuTituloOmdb = gson.fromJson(busca.buscaOmdb(filme), TituloOmdb.class);
return new Titulo(meuTituloOmdb);
}
public void salvaJson(List<Titulo> titulos) {
try {
FileWriter escrita = new FileWriter("filmes.json");
escrita.write(gson.toJson(titulos));
escrita.close();
} catch (IOException e) {
throw new ErroSalvarJsonException("Não foi possível salvar a sua lista de filmes");
}
}
}
E, por fim, assim ficou a classe Principal:
package br.com.alura.screenmatch.principal;
import br.com.alura.screenmatch.api.ManipulaJson;
import br.com.alura.screenmatch.excecao.ErroDeConversaoDeAnoException;
import br.com.alura.screenmatch.excecao.ErroSalvarJsonException;
import br.com.alura.screenmatch.excecao.ErroTituloNaoEncontradoException;
import br.com.alura.screenmatch.modelo.Titulo;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Principal {
public static void main(String[] args) throws RuntimeException {
Scanner leitura = new Scanner(System.in);
ManipulaJson busca = new ManipulaJson();
List<Titulo> titulos = new ArrayList<>();
while (true) {
System.out.println("Digite um filme para pesquisa:");
var filme = leitura.nextLine();
if (filme.equalsIgnoreCase("sair")) {
if (!titulos.isEmpty()) {
try {
busca.salvaJson(titulos);
} catch (ErroSalvarJsonException e) {
System.out.println(e.getMessage());
}
}
break;
}
try {
Titulo novoTitulo = busca.converteTitulo(filme);
titulos.add(novoTitulo);
System.out.println(novoTitulo);
} catch (ErroDeConversaoDeAnoException | ErroTituloNaoEncontradoException e) {
System.out.println(e.getMessage());
}
}
}
}