我一直在尝试使用gson将SignalK json转换为可寻址对象,但我遇到的挑战是SignalK定义有不同的方法来嵌套“Values”元素。 如果我通过使用gson.fromJson(json,MyClass.class)为每个嵌套“Values”元素的方法定义一个类,但我必须为表示“Values”的每种方式定义一个类,我才能使用它。领域似乎很复杂。 有没有办法可以使用gson(或其他东西)并生成一个跟随json模式的对象运行时?我试过用TypeToken查看泛型类型,但没有成功。 以下是不同“值”字段格式的两个示例:
示例1:
{
"context": "vessels.urn:mrn:signalk:uuid:333037323031",
"updates": [{
"source": {
"type": "NMEA0183",
"talker": "GN",
"sentence": "RMC",
"label": "N0183-01"
},
"timestamp": "2018-03-21T18:50:31Z",
"values": [{
"path": "navigation.position",
"value": {
"longitude": 09.501361,
"latitude": 51.763695
}
}
]
}
]}
示例2:
{
"context": "vessels.urn:mrn:signalk:uuid:333037323031",
"updates": [{
"source": {
"type": "NMEA0183",
"talker": "GN",
"sentence": "RMC",
"label": "N0183-01"
},
"timestamp": "2018-03-21T18:50:31Z",
"values": [{
"path": "navigation.courseOverGroundTrue",
"value": 12.236576
}, {
"path": "navigation.speedOverGround",
"value": 5.005144
}
]
}
]}
答案 0 :(得分:0)
看起来您实际上正在寻找一种方法来匹配代表具有path
值的类型的value
。
RuntimeTypeAdapterFactory
存在于Gson的世界中以满足这样的要求。
这个类不是Gson的一部分,但您可以简单地下载它并将其作为代码库的一部分,以便与其余代码一起编译。
首先,定义一个简单的值类型来表示一个位置,因为它非常类似于下面示例中使用的另一个值类型java.lang.Double
:
final class Position {
final double longitude = Double.valueOf(0); // Merely 0 makes javac inline this value to a constant, so we're cheating
final double latitude = Double.valueOf(0);
@Override
public String toString() {
return "(" + latitude + ";" + longitude + ")";
}
}
然后,为简单起见,定义一组简单的属性缩减映射:
final class Wrapper {
final List<Update> updates = null;
}
final class Update {
final List<AbstractValue<?>> values = null;
}
abstract class AbstractValue<T> {
final T value = null;
@Override
public final String toString() {
return String.valueOf(value);
}
}
现在我们可以定义多态值:
final class NavigationPositionValue
extends AbstractValue<Position> {
}
final class NavigationSpeedOverGroundValue
extends AbstractValue<Double> {
}
final class NavigationCourseOverGroundTrueValue
extends AbstractValue<Double> {
}
现在,我们可以将path
值映射到各自的预期类型,并测试构建的Gson
实例:
private static final Gson gson = new GsonBuilder()
.registerTypeAdapterFactory(RuntimeTypeAdapterFactory.of(AbstractValue.class, "path")
.registerSubtype(NavigationPositionValue.class, "navigation.position")
.registerSubtype(NavigationCourseOverGroundTrueValue.class, "navigation.courseOverGroundTrue")
.registerSubtype(NavigationSpeedOverGroundValue.class, "navigation.speedOverGround")
)
.create();
public static void main(final String... args)
throws IOException {
for ( final String resourceName : ImmutableList.of("example1.json", "example2.json") ) {
try ( final JsonReader jsonReader = Resources.getPackageResourceJsonReader(Q49505838.class, resourceName) ) {
System.out.println(resourceName);
final Wrapper wrapper = gson.fromJson(jsonReader, Wrapper.class);
for ( final Update update : wrapper.updates ) {
for ( final Object value : update.values ) {
System.out.println("\t" + value);
}
}
}
}
}
这将产生以下输出:
example1.json
(51.763695;9.501361)
example2.json
12.236576
5.005144