2
votes

Comment désérialiser une mappe clé-valeur en une liste

Je souhaite travailler avec les données cryptographiques décrites ici dans mon application de démarrage de printemps. Le RESTTemplate utilise Gson pour la désérialisation. Les données de réponse ressemblent à:

public class Symbol {
    private Long id; // not relevant during conversion
    private Date timestamp; // not relevant during conversion
    private String symbol;
    private Double eurPrice;
    private Double usdPrice;
}

J'ai déjà écrit un désérialiseur personnalisé auparavant. Le problème est que cela se présente sous la forme d'un objet unique avec des paires clé-valeur installées sous forme de tableau. Le résultat devrait être une liste des objets suivants:

{
  "IOST": {
    "EUR": 0.01147,
    "USD": 0.01296
  },
  "XRP": {
    "EUR": 0.2837,
    "USD": 0.3208
  },
  ...
}

Une idée de la façon dont cela peut être accompli?


0 commentaires

3 Réponses :


0
votes

Vous devez créer une classe comme ci-dessous

try {
        HashMap<String, Symbol> multiMap = new HashMap<String, Symbol>();
        JSONObject mJsonObject = new JSONObject(mResponse);
        Iterator<String> iter = mJsonObject.keys();
        while (iter.hasNext()) {
            String key = iter.next();
            try {
                Symbol msymbol = new Symbol();
                msymbol.setEUR(mJsonObject.getJSONObject(key).getDouble("EUR"));
                msymbol.setEUR(mJsonObject.getJSONObject(key).getDouble("USD"));
                multiMap.put(key, msymbol);

            } catch (JSONException e) {
                // Something went wrong!
            }
        }



    }catch (Exception e){
        e.printStackTrace();
    }

Ci-dessus est un modèle et ci-dessous est une analyse

public class Symbol  {

    private double EUR;
    private double USD;

    public double getEUR() {
        return EUR;
    }

    public void setEUR(double EUR) {
        this.EUR = EUR;
    }

    public double getUSD() {
        return USD;
    }

    public void setUSD(double USD) {
        this.USD = USD;
    }
}


7 commentaires

En outre, vous pouvez installer un plugin Gson Format dans votre Android Studio et créer une classe de modèle. C'est facile a utiliser


Cela ne fonctionnera pas. La réponse est une carte, donc IOST et XRP ne sont que des exemples de clés fournies par l'OP.


Le convertir en un gros objet fonctionnerait, mais ce n'est pas exactement ce que je veux. XRP et IOST ne sont que deux exemples de valeurs. Il y en a beaucoup et ceux qui sont utilisés ne doivent pas être codés en dur.


alors s'il vous plaît vous fournir une réponse réelle


Cela devrait pouvoir différer. Voici une réponse complète: {"IOST": {"EUR": 0.01147, "USD": 0.01296}, "XRP": {"EUR": 0.2837, "U‌ SD": 0.3208}, "LTC" : {"‌ EUR": 70,28, "USD": 79.‌ 43}, "BCH": {"EUR": 280‌ .85, "USD": 318.41}, "E‌ OS": {" EUR ": 4.78," USD‌ ": 5.42}," XLM ": {" EUR "‌: 0.1001," USD ": 0.1148‌}," ADA ": {" EUR ": 0.072‌ 7," USD ": 0,08201}," TR‌ X ": {" EUR ": 0,02333," U‌ SD ": 0,02648}," XMR ": {‌" EUR ": 57,61," USD ": 64‌ .94} , "NEO": {"EUR": 9.‌ 54, "USD": 10.82}, "VET‌": {"EUR": 0,006085, "U‌ SD": 0,006877}, "RVN": ‌ {"EUR": 0,05091, "USD" ‌: 0,05752}, "WAN": {"EU‌ R": 0,3643, "USD": 0,41‌ 16}, "WABI": {"EUR": 0. ‌ 4313, "USD": 0.4872}, "‌ BTT": {"EUR": 0.000674‌ 7, "USD": 0.0007622}}


J'ai mis à jour mon contrôle de réponse, vous pouvez le faire en utilisant ceci si vous travaillez puis acceptez ma réponse


@Madhu Bhat, je pense que cela fonctionne bien aussi j'ai vérifié



1
votes

Comme la réponse de cette API est dynamique et dépend des paramètres, le meilleur choix est d'utiliser une structure dynamique du côté de la désérialisation. Le meilleur choix est Carte . Comme clés, vous pouvez utiliser String ou enum : Currency , Crypto . Après la désérialisation, vous pouvez convertir Map en classe POJO requise. Exemple simple:

[Symbol{id=null, timestamp=null, symbol='IOST', eurPrice=0.01147, usdPrice=0.01296}, Symbol{id=null, timestamp=null, symbol='XRP', eurPrice=0.2837, usdPrice=0.3208}]

L'exemple ci-dessus imprime:

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class GsonTest {

    public static void main(String[] args) {
        String json = "{\"IOST\": {"
            + "    \"EUR\": 0.01147,"
            + "    \"USD\": 0.01296"
            + "  },"
            + "  \"XRP\": {"
            + "    \"EUR\": 0.2837,"
            + "    \"USD\": 0.3208"
            + "}}";

        Gson gson = new GsonBuilder().create();
        Type type = new TypeToken<Map<String, Map<Currency, BigDecimal>>>() {
        }.getType();

        Map<String, Map<Currency, BigDecimal>> response = gson.fromJson(json, type);

        List<Symbol> symbols = response.entrySet()
            .stream()
            .map(e -> {
                Symbol symbol = new Symbol();
                symbol.setSymbol(e.getKey());
                symbol.setEurPrice(
                    e.getValue().getOrDefault(Currency.EUR, BigDecimal.ZERO).doubleValue());
                symbol.setUsdPrice(
                    e.getValue().getOrDefault(Currency.USD, BigDecimal.ZERO).doubleValue());

                return symbol;
            }).collect(Collectors.toList());

        System.out.println(symbols);
    }

    enum Currency {
        EUR,
        USD
    }
}

Si vous voulez créer directement Liste de Symbole -s dont vous avez besoin pour implémenter un désérialiseur personnalisé. Par exemple, jetez un œil à cette question: Analyse du tableau JSON en liste Java Utilisation de Gson


0 commentaires

0
votes

L'anweser de Haresh ne correspondait pas à 100%, mais cela m'a aidé à comprendre:

var url = "...";
var entries = new ArrayList<Symbol>();
var timestamp = Timestamp.from(Instant.now());
Symbol symbol;

ResponseEntity<JsonObject> response = restTemplate.getForEntity(url, JsonObject.class);

for (Map.Entry<String, JsonElement> entry : response.getBody().entrySet()) {
    symbol = new Symbol();
    symbol.setSymbol(entry.getKey());
    symbol.setEurPrice(entry.getValue().getAsJsonObject().get("EUR").getAsDouble());
    symbol.setUsdPrice(entry.getValue().getAsJsonObject().get("USD").getAsDouble());
    symbol.setTimestamp(timestamp);

    entries.add(symbol);
}

Cela fait l'affaire. Cependant, si quelqu'un trouve un moyen de le faire complètement dans un désérialiseur Gson, j'aimerais l'entendre!


0 commentaires