2015-05-07 5 views
1

Я работаю с устаревшей системой, которая может иметь JSON, которые могут либо выглядеть:значение Deserialize, которое может быть целым или строкой

{"gauge": 1.0} 
// or 
{"gauge": "1.0-2.0"} 

который должен сказать, что gauge может быть либо целым числом или строкой , Я хочу иметь возможность сериализовать и десериализовать значение для одного и того же типа.

Сначала я думал, что я мог бы просто создать адаптер для этого:

public class Capabilities { 
    private Range gauge; 
} 
public class Range { 
    private int value; 
    private String range; 
    private boolean isRange; 

    public Range(int value) { 
    this.value = value; 
    this.isRange = false; 
    } 

    public Range(String value) { 
    this.range = range; 
    this.isRange = true; 
    } 

    public boolean isRange() { 
    return this.isRange; 
    } 

    public int getValue() { 
    return this.value; 
    } 

    public String getRange() { 
    return this.range; 
    } 
} 

Тогда я RangeTypeAdapter, что создает Range с Int значения/String в зависимости от обстоятельств.

Однако, когда я бегу gson.fromJson(str, Capabilities.class) я получаю:

Expected BEGIN_OBJECT but was STRING

Я убедился, что это происходит потому, что значение gauge в str является завернутые в двойных кавычках, и тот факт, что gauge должен быть Range или ничего, кроме String, означает, что он ожидает, что он станет объектом.

Есть ли способ ожидать, что Gson ожидает STRING для определенного класса? Более того, есть ли лучший способ обработки возможной дисперсии в примитивном типе?

+0

У вас есть доступ и контроль над классом исходного кода bean (POJO)? если да, я могу предложить ответ с помощью 'gauge' getter – Yazan

+0

@Yazan Я не слишком хорошо знаком с Java и честно не знаю, что означает« исходный код класса POJO », но я создал« Возможности »,« Диапазон » ',' RangeTypeAdapter' и класс, который выполняет 'gson.fromJson' –

+0

bean или POJO Я имею в виду класс, который будет использоваться для сериализации или десериализации JSON (используя GSON), в любом случае я отправляю ответ :) надеюсь, что это поможет вам – Yazan

ответ

0

Я не знаю, предоставил ли GSS API такой способ, но вариант должен был бы попробовать одно преобразование, а если он не прошел, попробуйте второй. Я хочу сказать, что у меня есть класс GaugeInt, который имеет gauge как поле int. И иметь другой класс, GaugeString, который имеет gauge как поле String. Теперь мы могли бы принять первое преобразование, скажем, GaugeInt.class; если это вызывает исключение, мы попробуем второе преобразование с GaugeInt.class.

+0

Для этого потребуется несколько раз запустить '.fromJson'? Я понимаю ваше предложение, но есть больше значений, чем 'gauge', которые делают это, поэтому мне нужно было бы создать множество классов для обработки примитивов, таких как' CapabilitiesWithGaugeIntWidthIntAlloyInt', 'CapabilitiesWithGaugeStringWidthIntAlloyInt' и т. Д. –

0
private String gauge = ""; 

public boolean isRange(){ 
     return (gauge.indexOf("-")>-1); 
} 

public int getValue(){ 
    if(isRange()){ 
     return Integer.parseInt(gauge.split("-")[0]); 
    }else{ 
     return Integer.parseInt(gauge); 
    } 
} 

public int getSecondValue(){ 
    if(isRange()){ 
     return Integer.parseInt(gauge.split("-")[1]); 
    }else{ 
     return -1; 
    } 
} 

так, позвонив isRange() вы Findout, если его 1.0 or 1.0-2.0, затем на основе этого вы можете либо

вызов getValue(),

или getValue() и getSecondValue()

, который в случае диапазон вернет второй int и если диапазон не вернется -1 или выберите другой номер для идентификации этого случая

нет необходимости в других адаптерах или около того.

надеюсь, что это вам поможет.

+0

Спасибо за ваше предложение для адаптера , но это не проблема. Проблема в том, что Gson, по-видимому, не позволяет вам указывать свои собственные классы для примитивов. Для этого требуется, чтобы у JSON был объект, в котором будет использоваться пользовательский класс. –

Смежные вопросы