Как получить базовую строку из JsonParser (Джексон Джсон)

Здесь мои 2 цента.

Или вы можете использовать простой метод с дженериками. Кусок торта.

public static <K,V> Map<V, K> invertMap(Map<K, V> toInvert) {
    Map<V, K> result = new HashMap<V, K>();
    for(K k: toInvert.keySet()){
        result.put(toInvert.get(k), k);
    }
    return result;
}

Конечно, у вас должна быть карта с уникальными значениями. В противном случае один из них будет заменен.

17
задан Puja 14 September 2018 в 06:16
поделиться

4 ответа

У меня была ситуация, когда я использовал настраиваемый десериализатор, но я хотел, чтобы стандартный десериализатор выполнял большую часть работы, а затем, используя SAME json, выполнял некоторые дополнительные настраиваемые действия. Однако после того, как десериализатор по умолчанию выполнил свою работу, текущее местоположение объекта JsonParser вышло за рамки необходимого мне текста json. Поэтому у меня возникла та же проблема, что и у вас: как получить доступ к базовой строке json.

Вы можете использовать JsonParser.getCurrentLocation.getSourceRef(), чтобы получить доступ к исходному источнику json. Используйте JsonParser.getCurrentLocation().getCharOffset(), чтобы найти текущее местоположение в источнике json.

Вот решение, которое я использовал:

public class WalkStepDeserializer extends StdDeserializer<WalkStep> implements
    ResolvableDeserializer {

    // constructor, logger, and ResolvableDeserializer methods not shown

    @Override
    public MyObj deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException,
            JsonProcessingException {
        MyObj myObj = null;

        JsonLocation startLocation = jp.getCurrentLocation();
        long charOffsetStart = startLocation.getCharOffset();

        try {
            myObj = (MyObj) defaultDeserializer.deserialize(jp, ctxt);
        } catch (UnrecognizedPropertyException e) {
            logger.info(e.getMessage());
        }

        JsonLocation endLocation = jp.getCurrentLocation();
        long charOffsetEnd = endLocation.getCharOffset();
        String jsonSubString = endLocation.getSourceRef().toString().substring((int)charOffsetStart - 1, (int)charOffsetEnd);
        logger.info(strWalkStep);

        // Special logic - use JsonLocation.getSourceRef() to get and use the entire Json
        // string for further processing

        return myObj;
    }
}

И информация об использовании десериализатора по умолчанию в пользовательском десериализаторе находится в . Как мне вызвать десериализатор по умолчанию из пользовательского десериализатора в Джексоне

5
ответ дан Community 14 September 2018 в 06:16
поделиться

5 лет спустя, но это было мое решение:

Я преобразовал jsonParser в строку

String requestString = jsonParser.readValueAsTree().toString();

Затем я преобразовал эту строку в JsonParser

JsonFactory factory = new JsonFactory();
JsonParser parser  = factory.createParser(requestString);

Затем я перебрал свой синтаксический анализатор

ObjectMapper objectMapper = new ObjectMapper();
while(!parser.isClosed()){
    JsonToken jsonToken = parser.nextToken();
    if(JsonToken.FIELD_NAME.equals(jsonToken)){
        String currentName = parser.getCurrentName();
        parser.nextToken();
        switch (currentName) {
            case "someObject":
                Object someObject = objectMapper.readValue(parser, Object.class)
                //validate someObject
                break;
        }
 }

Мне нужно было сохранить исходную строку json для целей регистрации, поэтому я сделал это в первую очередь. Была головная боль, чтобы узнать, но наконец сделал это, и я надеюсь, что помогу кому-то :))

3
ответ дан adbar 14 September 2018 в 06:16
поделиться

То, что вы пытаетесь сделать, выходит за рамки сферы деятельности Джексона (и большинства, если не всех других библиотек Java JSON). Что вы хотите сделать, так это полностью использовать входной поток в строку, а затем попытаться преобразовать эту строку в объект JSON с помощью Jackson. Если преобразование завершится неудачно, сделайте что-нибудь с промежуточной строкой, иначе продолжайте в обычном режиме. Вот пример, который для удобства использует превосходную библиотеку Apache Commons IO :

final InputStream stream ; // Your stream here

final String json = IOUtils.toString(stream);
try {
    final JsonNode node = new ObjectMapper().readTree(json);
    // Do something with JSON object here
} catch(final JsonProcessingException jpe) {
    // Do something with intermediate string here
}
2
ответ дан Perception 14 September 2018 в 06:16
поделиться

Создание собственного десериализатора, в котором я хотел десериализовать определенное поле в виде текста i.s.o. правильное DTO, это решение, которое я придумал.

Я написал свой собственный JsonToStringDeserializer следующим образом:

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.TreeNode;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringEscapeUtils;

import java.io.IOException;

/**
 * Deserialiser to deserialise any Json content to a String.
 */
@NoArgsConstructor
public class JsonToStringDeserializer extends JsonDeserializer<String> {


    /**
     * Deserialise a Json attribute that is a fully fledged Json object, into a {@link String}.
     * @param jsonParser Parsed used for reading JSON content
     * @param context Context that can be used to access information about this deserialization activity.
     * @return The deserialized value as a {@link String}.
     * @throws IOException
     */
    @Override
    public String deserialize(JsonParser jsonParser, DeserializationContext context) throws IOException {

        final TreeNode node = jsonParser.getCodec().readTree(jsonParser);

        final String unescapedString = StringEscapeUtils.unescapeJava(node.toString());
        return unescapedString.substring(1, unescapedString.length()-1);
    }
}

Аннотируйте поле, которое вы хотите десериализовать, следующим образом:

@JsonDeserialize(using = JsonToStringDeserializer.class)

Сначала я следовал совету, который сказал использовать TreeNode как this:

    final TreeNode treeNode = jsonParser.getCodec().readTree(jsonParser);
    return treeNode.toString();

Но тогда вы получите строку Json, которая содержит escape-символы.

2
ответ дан Leon Bedeker 14 September 2018 в 06:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: