Groovy映射构造函数键到不同的变量名称

时间:2017-05-25 10:03:09

标签: groovy

我有JSON看起来像:

{
    "days": [
        {
            "mintemp": "21.8"
        }
    ]
}

使用Groovy,我解析它:

class WeatherRow {
    String mintemp
}

def file = new File("data.json")
def slurper = new JsonSlurper().parse(file)
def days = slurper.days
def firstRow = days[0] as WeatherRow
println firstRow.mintemp

但实际上,我想将我的实例变量命名为minTemp(甚至是完全随机的,如numberOfPonies)。在Groovy中有一种方法可以将传递给构造函数的地图成员映射到其他地方吗?

为了澄清,我正在寻找@XmlElement(name="mintemp")的内容,但却找不到它:

class WeatherRow {
    @Element(name="mintemp")
    String minTemp
}

2 个答案:

答案 0 :(得分:1)

创建一个带地图的构造函数。

可运行的例子:

import groovy.json.JsonSlurper

def testJsonStr = '''
{"days": [
    { "mintemp": "21.8" }
]}'''

class WeatherRow {
    String minTemp
    WeatherRow(map) {
        println "Got called with constructor that takes a map: $map"
        minTemp = map.mintemp
    }
}

def slurper = new JsonSlurper().parseText(testJsonStr)
def days = slurper.days
def firstRow = days[0] as WeatherRow
println firstRow.minTemp

结果:

Got called with constructor that takes a map: [mintemp:21.8]
21.8

(当然你要删除println行,它只是用于演示)

答案 1 :(得分:0)

您可以使用注释和简单的自定义注释处理器实现此目的:

1。创建自定义注释类

@Retention(RetentionPolicy.RUNTIME)  
@interface JsonDeserializer {  
String[] names() default []
}

2。使用自定义注释

注释实例字段
class WeatherRow{

@JsonDeserializer(names = ["mintemp"])
String mintemp;

@JsonDeserializer(names = ["mintemp"])
String minTemp;

@JsonDeserializer(names = ["mintemp"])
String numberOfPonies;

}

3。使用注释处理添加自定义json反序列化器方法:

static WeatherRow fromJson(def jsonObject){

    WeatherRow weatherRow = new WeatherRow();
   try{
       weatherRow = new WeatherRow(jsonObject);
      }catch(MissingPropertyException ex){
      //swallow missing property exception.
      }

   WeatherRow.class.getDeclaredFields().each{

       def jsonDeserializer = it.getDeclaredAnnotations()?.find{it.annotationType() == JsonDeserializer}
       def fieldNames = [];

       fieldNames << it.name;

       if(jsonDeserializer){
        fieldNames.addAll(jsonDeserializer.names());

        fieldNames.each{i ->
            if(jsonObject."$i")//TODO: if field type is not String type custom parsing here.
                weatherRow."${it.name}" = jsonObject."$i";
        }

       }

    };

return weatherRow;

}

示例:

def testJsonStr = '''
{
    "days": [
        {
            "mintemp": "21.8"
        }
    ]
}'''

def parsedWeatherRows = new JsonSlurper().parseText(testJsonStr);

assert WeatherRow.fromJson(parsedWeatherRows.days[0]).mintemp == "21.8"
assert WeatherRow.fromJson(parsedWeatherRows.days[0]).minTemp == "21.8"
assert WeatherRow.fromJson(parsedWeatherRows.days[0]).numberOfPonies == "21.8"

检查groovyConsole处的完整工作代码。