Converter um array json em um ArrayList<T>

Bom dia a todos,
estou com um problema ao ler um json e tentar convertê-lo em um tipo generico.
se vocês olharem o codigo abaixo eu tenho dois metodos que fazem a mesma coisa porem so trocam a classe
eu gostaria de construir apenas um metodo estatico e ele seria o responsavel pela conversão de qualquer json para qualquer classe do meu sistema
como eu implementaria generics nessa classe ?

  private List converterJsonToListDescontoUfCondicao(String json) {
        Gson gson = getGson();
        Type listType = new TypeToken<Map<String,List<DescontoUfCondicao>>>() {}.getType();
        Map<String,List<DescontoUfCondicao>> mapa = gson.fromJson(json, listType);
        List<DescontoUfCondicao> lista = null;
        for( String key : mapa.keySet()){
           lista = mapa.get(key);     
        }
        
        return lista;
    }

    private List converterJsonToListDescontoProdutoCondicao(String json) {
        Gson gson = getGson();
        Type listType = new TypeToken<Map<String,List<DescontoProdutoCondicao>>>() {}.getType();
        Map<String,List<DescontoProdutoCondicao>> mapa = gson.fromJson(json, listType);
        List<DescontoProdutoCondicao> lista = null;
        for( String key : mapa.keySet()){
           lista = mapa.get(key);     
        }
        
        return lista;
    }

Rodrigo estou com um script parecido com o seu…

pra essa linha aqui, qual import vc está usando?

Type listType = new TypeToken<Map<String,List<DescontoUfCondicao>>>() {}.getType(); 

abs

Tenta passar além da string json uma instancia de Class ai tu faz assim

// Pega uma referencia a class private List converterJsonToListDescontoProdutoCondicao(String json, Class<T> classe) { Gson gson = getGson(); // Obtem uma instancia de TypeToken a partir dela e gera o Type como antes Type listType = TypeToken.get(classe).getType(); // Como no retorno não foi determinado um tipo e é possivel fazer um cast com segurança // e internamente no metodo não é utilizado nada do list eu fiz assim com Object Map<String, Object> mapa = gson.fromJson(json, listType); List<Object> lista = null; for( String key : mapa.keySet()){ lista = mapa.get(key); } return lista; }

Eu não testei o codigo e nunca utilizei esta API para json mas de acordo com a documentação acho que dá certo, testa ai e dá o feedback, o retorno poderia ser mais especifico caso fosse utilizado em uma classe a parte com a utilização de generics e os metodos poderiam ser sobrecarregados pra abranger um escopo maior, mas acho que assim funciona, só vai dar problema caso o a string não resulte em um List, acho que com reflection dá pra resolver isso.

[quote=salmaox]Rodrigo estou com um script parecido com o seu…

pra essa linha aqui, qual import vc está usando?

Type listType = new TypeToken<Map<String,List<DescontoUfCondicao>>>() {}.getType(); 

abs[/quote]

Salmaox

segue abaixo lista de imports de uma classe minha de testes:


import com.google.gson.*;
import com.google.gson.reflect.TypeToken;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import java.io.*;
import java.lang.reflect.Type;
import java.net.URISyntaxException;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;
import org.codehaus.jettison.json.JSONException;

[quote=CharlesAlves]Tenta passar além da string json uma instancia de Class ai tu faz assim

// Pega uma referencia a class private List converterJsonToListDescontoProdutoCondicao(String json, Class<T> classe) { Gson gson = getGson(); // Obtem uma instancia de TypeToken a partir dela e gera o Type como antes Type listType = TypeToken.get(classe).getType(); // Como no retorno não foi determinado um tipo e é possivel fazer um cast com segurança // e internamente no metodo não é utilizado nada do list eu fiz assim com Object Map<String, Object> mapa = gson.fromJson(json, listType); List<Object> lista = null; for( String key : mapa.keySet()){ lista = mapa.get(key); } return lista; }

Eu não testei o codigo e nunca utilizei esta API para json mas de acordo com a documentação acho que dá certo, testa ai e dá o feedback, o retorno poderia ser mais especifico caso fosse utilizado em uma classe a parte com a utilização de generics e os metodos poderiam ser sobrecarregados pra abranger um escopo maior, mas acho que assim funciona, só vai dar problema caso o a string não resulte em um List, acho que com reflection dá pra resolver isso.[/quote]

CharlesAlves,
Se eu tento converter para Object não gera nenhum erro,
agora seu eu tentar converter para ele me retorna um LinkedHashMap e da erro, estou postando minha classe abaixo.

package app;


import com.google.gson.*;
import com.google.gson.reflect.TypeToken;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import java.io.*;
import java.lang.reflect.Type;
import java.net.URISyntaxException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.codehaus.jettison.json.JSONException;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author rodrigo
 */
public class Main {
    
    public static void main(String args[]) throws FileNotFoundException, IOException, URISyntaxException, JSONException{
        
        String json = readJsonFromFile();
        Gson gson = getGson();
        
        Type type = null;
        List<DescontoQuantidadeCondicao> lista = null ;

         // Primeiro conversao para object --> OK        
         // verifica se é um array 
 
        if( json.contains("[")){
            type = new TypeToken<Map<String,List<DescontoQuantidadeCondicao>>>(){}.getType();
            lista = (List<DescontoQuantidadeCondicao>) converterJsonToObject(json, type);
        }else{
            type = new TypeToken<Map<String,DescontoQuantidadeCondicao>>(){}.getType();
            lista = new ArrayList<DescontoQuantidadeCondicao>();
            lista.add((DescontoQuantidadeCondicao) converterJsonToObject(json, type));        
        }
        
        
        System.out.println(lista.get(0).getId());
        // saida esta ok ... 
        
        // agora tenta converter usando Generics        

        List<DescontoQuantidadeCondicao> lista2 = converterJsonToList(json, DescontoQuantidadeCondicao.class);
        
        
        System.out.println(lista2.get(0).getId());
        // da a seguinte mensagem de erro.
        //        Exception in thread "main" java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to app.DescontoQuantidadeCondicao
	// at app.Main.main(Main.java:59)        


        
    }
    
   private static Object converterJsonToObject( String json, Type type){
        Gson gson = getGson();
        Map<String, Object> mapa = gson.fromJson(json, type);
        Object obj = null;
        for( String key : mapa.keySet()){
           obj = mapa.get(key);     
        }
        return obj;
   } 
   
   private static <T> List<T> converterJsonToList(String json, Class<T> aClass) {
        
        Type type = null;
        List<T> lista = null ;
        
        if( json.contains("[")){
            type = new TypeToken<Map<String,List<T>>>(){}.getType();
            lista= (List<T>) converterJsonToObject(json, type);
        }else{
            type = new TypeToken<Map<String,T>>(){}.getType();
            lista = new ArrayList<T>();
            lista.add((T) converterJsonToObject(json, type));
        }
        return lista;
    }
    
    public static Gson getGson(){
        GsonBuilder builder = new GsonBuilder(); 
        String formato = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").toPattern();
        builder.setDateFormat(formato);
        return builder.create();
    }
    
    public static String readJsonFromFile() throws FileNotFoundException, URISyntaxException, IOException{
        File file = new File(Produto.class.getResource("desconto.js").toURI());
        BufferedReader br = new BufferedReader(new FileReader(file));
	String linha = "";
        String json  = "";
        
        while( (linha = br.readLine()) != null ){	  
          json += linha;
	}
	
        br.close();
        return json;
    }
    
    public static String readWebService(){
        
        ClientConfig cc = new DefaultClientConfig();
        Client cliente = Client.create(cc);
        WebResource wr = cliente.resource("http://localhost:8080/webservice").path("descontosquantidade");
        String resposta = wr.get(String.class);
        
        return resposta;
    }
}

Bom definitivamente desisto de tentar xD, to desde cedo tentando e não tem jeito a forma correta de fazer para pegar o list é assim mesmo

private List converterJsonToListDescontoProdutoCondicao(String json) { Type listType = new TypeToken<List<Teste>>(){}.getType(); List<Teste> lista = new Gson().fromJson(json, listType); return lista; }
Todas as vezes que tentei fazer utilizando generics ele não reconheceu o tipo e terminou fazendo uma instancia de Object, com isto ele terminava criando uma instancia de LinkedHashMap, por isto está dando lançando esta exception. Mas vou pesquisar mais, ainda não sei exatamente o porque de não estar dando certo e isto me incomoda.

Charles usei dessa forma também, deu certo…

Type collectionType = new TypeToken<List<Teste>>(){}.getType();
List<Teste> lista = g.fromJson(str, collectionType);

return lista;

O problema é ao usar generics salmaox…

Pois é estou com o mesmo erro, e o legal de usar o tipo generic é que se não for assim eu terei que criar uma classe para cada tipo que eu for deserializar.

:?