How to deserialize JSON using Gson with generic list?

Asked

Viewed 1,336 times

3

I need to deserialize JSON for a generic list, but I’m having an error that I believe is in the conversion:

Method call:

AtualizarJSON at = (AtualizarJSON) DeserializaConsulta(AtualizarJSON.class, resultadoJSON);

Method:

private <T> List<T> DeserializaConsulta(Class<T> tipo, String resultadoJSON) throws JSONException {
        if (resultadoJSON != null) {
            return Arrays.asList(new Gson().fromJson(resultadoJSON, tipo));
        }
        return null;
    }

inserir a descrição da imagem aqui

Request at the WS:

private String ConsultarOuBaixarAtualizacoes(String urlT) throws IOException {
        InputStream is = null;

        try {
            URL url = new URL(urlT);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(10000);
            conn.setConnectTimeout(15000);
            conn.setRequestMethod("GET");
            conn.setDoInput(true);
            conn.connect();
            conn.getResponseCode();

            is = conn.getInputStream();

            Reader reader = null;
            reader = new InputStreamReader(is, "UTF-8");
            char[] buffer = new char[2048];
            reader.read(buffer);

            return new String(buffer);
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

Caused by: com.google.gson.stream.Malformedjsonexception: Use Jsonreader.setLenient(true) to Accept malformed JSON at line 1 column 126

I believe that this solution is not ideal, because there must be a way to solve this problem by setting the types as I have seen in some examples, but I could not find examples for this case where I pass the type by parameter.

  • 1

    Could put a sample of JSON?

  • I’ve had problems with Gson and generic list, but I do not remember what it was, I think it is not possible to do the way you want (I may be wrong, tomorrow I see my project). However your error message indicates a problem even before the JSON conversion attempt, apparently you formed it wrong, try to check for errors in it. How it was generated?

  • I’ll put his return here, probably this is it, it comes correctly but the end of it comes a lot of weird characters

  • Place the sample within your question, because it is breaking the layout of the site hehe. Probably this must be some encoding problem. Try to check if the encoding of the answer is the same as your client expects. And I believe that by hitting this you don’t even need to use the setLenient.

  • @Math can not put the sample there, can not edit =/... put a return print via browser, it does not return this string ae... tested in 2 browsers.

  • @Wakim sure I’ll see it! Thanks!

  • @Wakim can check the request if there is something wrong? I added the question.

  • I believe it’s the buffer. Why don’t you use a BufferedReader to read all lines (using a StringBuilder)? 'Cause you’re probably having one String with 2048 characters where 60% is junk (old memory data).

  • @Wakim poe as an answer! I saw an example like this and I couldn’t do it. Thanks!

Show 4 more comments

1 answer

3


I believe these invalid characters come from the way you are reading, not from encoding as I assumed at the beginning.

When you allocate a char vector with 2048 positions and use to read the answer. You probably have 60% characters being previous values existing in heap memory. And this causes the problem of Parsing of the GSON.

I recommend reading the server response using a BufferedReader. Reading all lines until the end of the answer.

The code would be:

private String ConsultarOuBaixarAtualizacoes(String urlT) throws IOException {
    InputStream is = null;
    BufferedReader reader = null;

    try {
        URL url = new URL(urlT);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setReadTimeout(10000);
        conn.setConnectTimeout(15000);
        conn.setRequestMethod("GET");
        conn.setDoInput(true);
        conn.connect();
        conn.getResponseCode();

        is = conn.getInputStream();
        reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));

        StringBuilder sb = new StringBuilder();
        String line = null;

        // Le cada linha da resposta ate o final
        while((line = reader.readLine()) != null) {
            sb.append(line);
        }

        return sb.toString();
    } finally {
        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        if(reader != null) {
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
  • Caused by: java.lang.Classcastexception: java.util.Arrays$Arraylist cannot be cast to com.universo91.catalogo91_android.dto.Updatejson now the error is generated in the conversion! I mean, it worked but I still need something I must have done wrong in this conversion!

  • 1

    Ah... The mistake is that the method Deserializar will always return a list. Not just an object AtualizarJSON. Refactor the method to return directly new Gson().fromJson(resultadoJSON, tipo) or Switch the variable to List<AtualizarJSON> and take the first element.

  • You would have to refactor anyway, but shouldn’t you return a list with only one object? If you are going to do this, the method is practically invalid, because the reason for List<T> is to go back 1 or more... what is your advice to solve?

  • If it is to be generic, it is better to assign the return to a list and take the first element, without tampering with the method.

  • The error is in the method call outside, on the line where declares the variable "at"

Browser other questions tagged

You are not signed in. Login or sign up in order to post.