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

Erro ao pegar dados do servidor com Retrofit

Estou tendo dificuldades ao baixar os dados do WebService, quando vejo o logcat apresenta o seguinte erro:

Can not deserialize instance of java.util.ArrayList out of START_OBJECT token
                                                                      at [Source: okhttp3.ResponseBody$BomAwareReader@f778912; line: 1, column: 1]

Segue o modelo do webService

{"turmas":[{"codigo":"1","descricao":"TURMA 1"},{"codigo":"2","descricao":"TURMA 2"},{"codigo":"3","descricao":"TURMA 3"}]}

Estou usando o JacksonConverter;

7 respostas

Fala ai Ueder, algumas perguntas:

  • Como esta as configurações do Retrofit ?
  • Como esta seu Service ?
  • Como esta seu DTO ?

Poste um pouco mais dos códigos e logs de erro, para ficar mais fácil ajudar.

Abraços

Boa noite Matheus, Olha como eu descrevi o erro é esse aqui, a leitura do WebService faz normalmente tanto é que eu vejo a resposta pelo interceptor. Só que quando eu tento atribui-lo a uma lista gera esse erro abaixo.

1-13 23:26:07.783 6298-6298/br.com.ueder.agromobile E/onFailure:: Erro ao acessar: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token
                                                                    at [Source: okhttp3.ResponseBody$BomAwareReader@116e55f; line: 1, column: 1]

Model

public class Turma {

    private long codigo;
    private String descricao;

    public long getCodigo() {
        return codigo;
    }

    public String getDescricao() {
        return descricao;
    }

    public Turma(long codigo, String descricao) {
        this.codigo = codigo;
        this.descricao = descricao;
    }

    @Override
    public String toString() {
        return codigo + " - " + descricao;
    }
}

Service

public interface TurmaService {

    @GET ("cadastrosTurmas/turmas")
    Call<List<Turma>> getTurmas();
}

E o método que chama o service

 Call<List<Turma>> callTurmas = new RetrofitInstance(ctx).getTurmaService().getTurmas();
                    callTurmas.enqueue(new Callback<List<Turma>>() {
                        @Override
                        public void onResponse(Call<List<Turma>> call, Response<List<Turma>> response) {
                            List<Turma> turmas = response.body();
                            Log.e("onResponse ",  "deu certo" );
                        }

                        @Override
                        public void onFailure(Call<List<Turma>> call, Throwable t) {
                            Log.e("onFailure: ", "Erro ao acessar: " + t.getMessage() );
                        }
                    });

Classe do Retrofit

public RetrofitInstance(Activity ctx) {

        String porta = Preferencia.getInstance(ctx).getPorta();
        String endereco =  Preferencia.getInstance(ctx).getEndereco().startsWith("http://") == true ? Preferencia.getInstance(ctx).getEndereco() : "http://" + Preferencia.getInstance(ctx).getEndereco();
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient.Builder client = new OkHttpClient.Builder();
        client.addInterceptor(interceptor);

        String baseUrl = endereco + ":" + porta + "/ws-ponto/";
        retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .client(client.build())
                .addConverterFactory(JacksonConverterFactory.create())
                .build();
    }

    public TurmaService getTurmaService() {
        return retrofit.create(TurmaService.class);
    }

Olhando rapidamente não consegui ver erro no código, consegue logar o response.body() para vermos o que esta chegando ?

Segue o log Matheus, eu ainda não consegui compreender.

Se eu fizer manual até consigo, mas usando o Retrofit até agora nada.

11-14 00:09:22.318 5526-5819/br.com.ueder.agromobile D/OkHttp: Content-Type: application/json
11-14 00:09:22.318 5526-5819/br.com.ueder.agromobile D/OkHttp: Transfer-Encoding: chunked
11-14 00:09:22.318 5526-5819/br.com.ueder.agromobile D/OkHttp: Date: Tue, 14 Nov 2017 00:09:18 GMT
11-14 00:09:22.320 5526-5819/br.com.ueder.agromobile D/OkHttp: {"turmas":[{"codigo":"1","descricao":"BOM JESUS 9"},{"codigo":"2","descricao":"BOM JESUS 1"},{"codigo":"3","descricao":"MEIA PONTE 1"},{"codigo":"4","descricao":"ROCADEIRA MANUAL"},{"codigo":"5","descricao":"IRRIGACAO"},{"codigo":"6","descricao":"Apoio NR-31"},{"codigo":"7","descricao":"JOVIANIA 1"},{"codigo":"8","descricao":"ALOANDIA 2A"},{"codigo":"9","descricao":"GOIATUBA 3"},{"codigo":"10","descricao":"BOM JESUS 4"},{"codigo":"11","descricao":"BOM JESUS 2"},{"codigo":"12","descricao":"BOM JESUS 3"},{"codigo":"18","descricao":"GOIATUBA 2"},{"codigo":"19","descricao":"ALOANDIA 1"},{"codigo":"20","descricao":"JOVIANIA 2"},{"codigo":"22","descricao":"BOM JESUS 5"},{"codigo":"23","descricao":"GOIATUBA 4"},{"codigo":"25","descricao":"BOM JESUS 7"},{"codigo":"26","descricao":"BOM JESUS 6"},{"codigo":"27","descricao":"BOM JESUS 8"},{"codigo":"33","descricao":"JOVIANIA 3"}]}
11-14 00:09:22.320 5526-5819/br.com.ueder.agromobile D/OkHttp: <-- END HTTP (882-byte body)
11-14 00:09:22.343 5526-5526/br.com.ueder.agromobile E/onFailure:: Erro ao acessar: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token
                                                                    at [Source: okhttp3.ResponseBody$BomAwareReader@71ccbac; line: 1, column: 1]
solução!

Certo, vamos fazer o seguinte, primeiro, crie esse DTO:

public class TurmaDTO {
    private List<Turma> turmas;

    public getTurmas() {
        return this.turmas;
    }
    public setTurmas(List<Turmas> turmas) {
        this.turmas = turmas;
    }

}

Agora precisamos fazer seu serviço retornar esse DTO e não mais uma lista de turmas:

public interface TurmaService {
    @GET ("cadastrosTurmas/turmas")
    Call<TurmaDTO> getTurmas();
}

E por fim, temos que acertar nossa Call:

Call<TurmaDTO> callTurmas = new RetrofitInstance(ctx).getTurmaService().getTurmas();
callTurmas.enqueue(new Callback<TurmaDTO>() {
    @Override
    public void onResponse(Call<TurmaDTO> call, Response<TurmaDTO> response) {
    TurmaDTO dto = response.body;
    List<Turma> turmas = dto.getTurmas();
    Log.e("onResponse ",  "deu certo" );
}

    @Override
    public void onFailure(Call<TurmaDTO> call, Throwable t) {
    Log.e("onFailure: ", "Erro ao acessar: " + t.getMessage() );
    }
});

Acho que irá resolver o problema.

Deu certo Matheus, muito obrigado pela ajuda. Um abraço.

De nada Ueder, sempre que precisar não deixe de criar suas dúvidas