Solucionado (ver solução)
Solucionado
(ver solução)
7
respostas

Unable to resolve host "api.github.com": No address associated with hostname

Olá. Preciso da seguinte ajuda: Estou tomando o erro descrito no título deste tópico. Porém, o endereço "api.github.com" existe. Eu utilizo ele no Retrofit, como URL base, mas não funciona. Alguém consegue ajudar? Segue abaixo código:

package br.com.nexas.appgithubjava.retrofit;

import br.com.nexas.appgithubjava.service.RepositorioService;
import retrofit2.Retrofit;
import retrofit2.converter.jackson.JacksonConverterFactory;

/**
 * Created by user on 02/11/2017.
 */

public class RepositorioRetrofit {

    private final Retrofit retrofit;
    private static final String BASE_URL = "https://api.github.com/";
    public RepositorioRetrofit(){
        retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(JacksonConverterFactory.create())
                .build();
    }

    public RepositorioService getRepositorioService(){
        return retrofit.create(RepositorioService.class);
    }
}
public interface RepositorioService {

    @GET("search/repositories?q=language:Java&sort=stars")
    Call<RepositorioDTO> getRepositorio(@Query("page") Integer page);

}
7 respostas

Oi Victor, tudo bem?

Tenho duas sugestões para essa situação:

  • Verificar se foi adicionada a permissão de acesso à internet no manifest.
  • Adicionar o Logging Interceptor para verificar o que está acontecendo na requisição.

Eu testei aqui também a URL via Postman e funciona mesmo... Provavelmente é algum problema de configuração mesmo.

Caso não resolver o problema de acordo com a orientação que passei, mande o código via GitHub que eu dou uma olhada.

[]s

Olá Alex. Adicionei o logging interceptor. Segue abaixo o que ele mostra. Se testar a URL no browser ele funciona normalmente. Mas no log diz que houve erro.

11-03 11:36:49.505 23779-23815/br.com.nexas.appgithubjava D/OkHttp: --> GET https://api.github.com/search/repositories?q=language:Java&sort=stars&page=0
11-03 11:36:49.505 23779-23815/br.com.nexas.appgithubjava D/OkHttp: --> END GET
11-03 11:36:49.505 1247-1514/? E/SurfaceFlinger: ro.sf.lcd_density must be defined as a build property

                                                 [ 11-03 11:36:49.508 23779:23779 D/         ]
                                                 HostConnection::get() New Host Connection established 0x8d8ff400, tid 23779


                                                 [ 11-03 11:36:49.510 23779:23779 W/         ]
                                                 Process pipe failed
11-03 11:36:49.519 23779-23815/br.com.nexas.appgithubjava D/OkHttp: <-- HTTP FAILED: java.net.UnknownHostException: Unable to resolve host "api.github.com": No address associated with hostname
11-03 11:36:49.547 1247-1514/? D/gralloc_ranchu: gralloc_alloc: format 1 and usage 0x900 imply creation of host color buffer

                                                 [ 11-03 11:36:49.549 23779:23816 D/         ]
                                                 HostConnection::get() New Host Connection established 0x8d8ff780, tid 23816
11-03 11:36:49.563 1247-1514/? D/gralloc_ranchu: gralloc_alloc: format 1 and usage 0x900 imply creation of host color buffer
11-03 11:36:49.570 23779-23816/br.com.nexas.appgithubjava I/OpenGLRenderer: Initialized EGL, version 1.4
11-03 11:36:49.570 23779-23816/br.com.nexas.appgithubjava D/OpenGLRenderer: Swap behavior 1
11-03 11:36:49.583 1247-1514/? D/gralloc_ranchu: gralloc_alloc: format 1 and usage 0x900 imply creation of host color buffer
11-03 11:36:49.606 23779-23779/br.com.nexas.appgithubjava E/onFailure chamado:: Unable to resolve host "api.github.com": No address associated with hostname
11-03 11:36:49.620 23779-23816/br.com.nexas.appgithubjava E/EGL_emulation: tid 23816: eglSurfaceAttrib(1146): error 0x3009 (EGL_BAD_MATCH)

Estranho mesmo... Não sei te dizer exatamente qual é o problema. Você poderia enviar o projeto via GitHub? Dessa forma eu consigo testar e verificar as possibilidades do problema, o que acha?

[]s

Ok, acabei de disponibilizar lá. Consegue ver? É este link: https://github.com/adrianoabreu/AppGitHubJava

solução!

oi Victor, entendi o problema, é justamente no objeto que está usando para realizar a conversão.

Repare que os campos que estão vindo no JSON são diferentes dos atributos que está marcando. Por padrão o Jackson quebra a App caso tenha algum campo que ele não consiga realizar o parse.

Evitando a falha para campos desconhecidos em uma classe específica

Para evitar esse erro, você pode realizar duas configurações, a primeira delas é anotar a classe que está sendo convertida com @JsonIgnoreProperties(ignoreUnknown = true), em código ficaria algo assim:

@JsonIgnoreProperties(ignoreUnknown = true)
public class RepositorioDTO {
    private List<Repositorio> repositorios;

    public List<Repositorio> getRepositorios() {
        return repositorios;
    }
}

Então, dessa forma, mesmo que não exista o campo que está no Jackson, a sua App não vai quebrar ao tentar converter essa classe. Porém, repare que você vai ter que configurar todas as classes desse jeito caso não queira esse comportamento...

Evitando a falha para campos desconhecidos em todas as classes por padrão

Para evitar essa config em todas as classes, você pode realizar essa config direto na criação do Retrofit:

ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

retrofit = new Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(JacksonConverterFactory.create(mapper))
        .client(client.build())
        .build();

A classe ObjectMapper é justamente a classe que representar o serializador e deserializador do Jackson, a chamada do método configure() enviando o paramêtro DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES significa que está sendo feita a configuração de falha para casos que venham campos desconhecidos (como é o caso de agora), então o parâmetro false, indica que esse comportamento não é desejado.

Por fim, basta apenas enviar o mapper dentro do create() do JacksonConverterFactory que todas as classes que forem convertidas por meio do Retrofit usando o Jackson, vão ter esse comportamento por padrão. Portanto, não precisa usar aquela annotation após aplicar essa configuração.

Indicando o campo esperado para um atributo

Agora, o único detalhe que precisa se atentar é no nome dos atributos, por exemplo, suponhamos que queira pegar o campo total_count do JSON que está vindo da API. Esse atributo seria do DTO, certo? A princípio faríamos algo do gênero considerando a tradução do parâmetro:

public class RepositorioDTO {

    private int contagemTotal;

    public int getContagemTotal() {
        return totalCount;
    }

    private List<Repositorio> repositorios;

    public List<Repositorio> getRepositorios() {
        return repositorios;
    }
}

Entretanto, repare que o Jackson não vai conseguir realizar o processo de bind entre o campo total_count e o contagemTotal, pois os nomes não batem! Mas é algo desejado por nós manter o valor nesse atributo, certo? Para isso, você pode usar a annotation @JsonProperty e enviar o campo que espera para esse atributo da seguinte maneira:

public class RepositorioDTO {

    @JsonProperty("total_count")
    private int contagemTotal;

    public int getContagemTotal() {
        return contagemTotal;
    }

    private List<Repositorio> repositorios;

    public List<Repositorio> getRepositorios() {
        return repositorios;
    }
}

Pronto! Dessa maneira o bind ocorre sem nenhum problema. Claro, infelizemente vai precisar fazer isso em todos os campos para casar o bind... Lembrando que se um campo não vier com o valor esperado, provalmente foi um problema de estrutura da classe que foi implementada.

Se tiver alguma dúvida é só avisar.

[]s

Ok Alex, consegui! Obrigado!

Ótimo Victor, então eu vou marcar como solucionado. Se tiver mais duvidas, fique a vontade em abrir mais tópicos no fórum.

[]s