web-dev-qa-db-fra.com

Jackson a lu la valeur sous forme de chaîne

J'ai un objet avec des valeurs inconnues, disons

{
 "data": [
    {"a":...,
    "dont_know_what_else_is_here":....}
 ]
}

Et je veux juste stocker la valeur de "data" en tant que chaîne dans une variable/base de données. 

Comment dois-je le lire à partir de l'API de streaming?

26
Edison

Si vous avez déjà lu cet objet dans JsonNode, vous pouvez le faire comme ceci:

String content = jsonNode.get("data").textValue();

UPD: puisque vous utilisez un analyseur de flux, this exemple sur l'utilisation de Jackson pourrait aider.

UPD: le nom de la méthode est maintenant textValue () - docs

35
Andrew Logvinov

Lorsque nous essayons d'extraire des données sous forme de chaîne à partir de JsonNode, nous utilisons généralement asText, mais nous devrions plutôt utiliser textValue.

asText : Méthode renvoyant une représentation sous forme de chaîne valide de la valeur du conteneur, si le nœud est un nœud de valeur (la méthode isValueNode () renvoie true), sinon String est vide.

textValue : Méthode à utiliser pour accéder aux valeurs de chaîne. Ne fait PAS de conversions pour les nœuds de valeur non-String; pour les valeurs non-String (celles pour lesquelles isTextual () renvoie false), null sera renvoyé. Pour les valeurs de chaîne, null n'est jamais renvoyé (mais des chaînes vides peuvent l'être)

Alors prenons un exemple,

JsonNode getJsonData(){
    ObjectMapper mapper = new ObjectMapper();
    ObjectNode node = mapper.createObjectNode(); 
    node.put("anyParameter",null);
    return node;
}
JsonNode node = getJsonData();
json.get("anyParameter").asText() // this will give output as "null"
json.get("").textValue() // this will give output as null
12
Mukul Aggarwal

Vous pouvez obtenir les données dans une carte en fonction de paires de valeurs clés.

Map<String, Object> mp = mapper.readValue(new File("xyz.txt"),new TypeReference<Map<String, Object>>() {});

Maintenant, obtenez la valeur de la carte:

mp.get("data");
6
dejavu

Vous pouvez avoir une classe d'entité pour un résultat JSON.

String json = "your_json";
ObjectMapper mapper = new ObjectMapper();
Entity entity = mapper .readValue(json, Entity.class);
// here you can do everything with entity as you wish

// to write Entity value as String when you wish
String text = mapper.writeValueAsString(object);
// to write Entity child's value as String when you wish (let's data contain data part)
String data = mapper.writeValueAsString(object.getData());
2
Igor K

En supposant que vous ayez déjà un analyseur et qu’il pointe vers le jeton "data" (par exemple à partir d’un désérialiseur personnalisé), vous pouvez effectuer les opérations suivantes:

ObjectMapper mapper = new ObjectMapper();
JsonNode treeNode = mapper.readTree(parser);
return treeNode.toString();

Cela vous donnera String contenant la valeur de "data".

2
Dmitry

Si vous utilisez String data dans createParser(data), j'utilise cette méthode pour collecter le contenu d'une chaîne avec une api en streaming

if ("data".equals(fieldname))
     String strData = getValueAsString(jp);

et

    private static String getValueAsString(JsonParser jp)
        throws com.fasterxml.jackson.core.JsonParseException, IOException {
    JsonToken token = jp.getCurrentToken();
    int counter = 0;

    long startIndex = jp.getCurrentLocation().getCharOffset();
    long endIndex = 0;

    if (token == JsonToken.START_OBJECT) {
        // JsonLocation location = jp.getCurrentLocation();
        // startIndex = location.getCharOffset();
        // System.out.println(",location=" + new Gson().toJson(location) +
        // ", start=" + startIndex);

        counter++;
        while (counter > 0) {
            token = jp.nextToken();
            if (token == JsonToken.START_OBJECT)
                counter++;
            if (token == JsonToken.END_OBJECT) {
                counter--;
                endIndex = jp.getCurrentLocation().getCharOffset();
            }
        }

        return data.substring((int) startIndex - 1, (int) endIndex);

    } else if (token == JsonToken.START_ARRAY) {
        counter++;
        while (counter > 0) {
            token = jp.nextToken();
            if (token == JsonToken.START_ARRAY)
                counter++;
            if (token == JsonToken.END_ARRAY) {
                counter--;
                endIndex = jp.getCurrentLocation().getCharOffset();
            }
        }
        return data.substring((int) startIndex - 1, (int) endIndex);

    } else {
        return jp.getText();
    }
}

cela fonctionne quand la source de données est String. pour aucune chaîne source telle que file, en utilisant JsonLocation.getByteOffset() au lieu de JsonLocation.getCharOffset()

0
oscarthecat

Enfin trouvé la solution à partir de la lecture de la page du tutoriel.

Juste pour donner aux autres un pointeur ici:

  1. Passez à l’utilisation de MappingJSONFactory lors de la création de l’analyseur:

        HttpResponse response = client.execute(request);
        JsonFactory jfactory = new MappingJsonFactory();
        JsonParser parser=jfactory.createJsonParser(response.getEntity().getContent());
    
  2. Ensuite, vous pouvez juste faire 

        parser.readValueAsTree().toString();
    

ou analysez comme bon vous semble. 

0
Edison

Supposons que vous ayez une classe Java POJO appelée User ( Tiré de ceci )

public class User {
public enum Gender { MALE, FEMALE };

public class Name {
    private String _first, _last;

    public String getFirst() { return _first; }
    public String getLast() { return _last; }

    public void setFirst(String s) { _first = s; }
    public void setLast(String s) { _last = s; }
}

private Gender _gender;
private Name _name;
private boolean _isVerified;
private byte[] _userImage;

public Name getName() { return _name; }
public boolean isVerified() { return _isVerified; }
public Gender getGender() { return _gender; }
public byte[] getUserImage() { return _userImage; }

public void setName(Name n) { _name = n; }
public void setVerified(boolean b) { _isVerified = b; }
public void setGender(Gender g) { _gender = g; }
public void setUserImage(byte[] b) { _userImage = b; }

}

Alors maintenant, vous avez une chaîne JSON qui vient de n’importe quel endroit quelque part comme une prise Web ou ailleurs. Par exemple, supposons que c’est la chaîne que vous obtenez. 

String json = "{\n" +
            "  \"name\" : { \"first\" : \"Joe\", \"last\" : \"Sixpack\" },\n" +
            "  \"gender\" : \"MALE\",\n" +
            "  \"verified\" : false,\n" +
            "  \"userImage\" : \"Rm9vYmFyIQ==\"\n" +
            "}";

Vous pouvez maintenant convertir cette chaîne JSON en objet POJO en utilisant simplement ce morceau de code.

ObjectMapper mapper = new ObjectMapper();
User user = mapper .readValue(json, User.class);
0
GPrathap

Je suppose que vous voulez simplement lire une sous-arborescence à partir d'une entrée à l'aide de Streaming API - mais au final, vous avez besoin d'une sous-arborescence entière comme une chose à stocker dans une base de données (ou variable).

Donc, ce que vous voulez probablement utiliser est JsonParser.readValueAs(MyType.class) - ceci appellera ObjectMapper (et pour que cela fonctionne, l'analyseur doit être créé via JsonFactory auquel on a accès à partir de ObjectMapper; ou vous devez appeler JsonFactory.setCodec(mapper)).

Si le contenu est arbitraire, vous pouvez le lire sous la forme Map ou JsonNode:

Map<String,Object> map = parser.readValueAs(Map.class);
// or
JsonNode root = parser.readValueAsTree();

dès que JsonParser pointe vers START_ELEMENT de l’objet JSON que vous souhaitez attribuer à l’identificateur de données.

0
StaxMan

Cela devrait fonctionner:

public static void main(String[] args) throws IOException {
    String content = new String(Files.readAllBytes(Paths.get("duke.Java")));
}

Je l'ai trouvé ici

0
horizon7