我正在阅读一个Json字符串,并使用scala代码将其转换为对象:
function exportcsv(){
var tabledata = $('selectorJquery').DataTable();
var table = tabledata._('tr', {"filter": "applied"});
var columns = tabledata.dataTableSettings[0].aoColumns;
var tableString = "";
//Get the title headers and add to the first line of .csv
$.each(columns, function(i,v) {
tableString += v.sTitle+";";
});
//Add line break and get the length of rows and the length of cols
tableString += "\r\n";
var rowLength = table.length;
var colLength = table[0].length;
//Iterate all rows and cols
for (var j = 0; j < rowLength; j++) {
for (var k = 0; k < colLength; k++) {
tableString += (k==colLength) ? table[j][k] : table[j][k]+";";
}
tableString += "\r\n";
}
//Put the headers of file, application/csv and charset UTF-8 with BOM and the string with data rows
csvData = 'data:application/csv;charset=utf-8,\uFEFF' + encodeURIComponent(tableString);
var d = new Date();
//Here I put in href attribute of a <a> HTML element and the .csv file starts to download automatically with name=yyyy-mm-dd_hh-mm-ss.csv
$('selectorJquery').attr({
'href': csvData,
'target': '_blank',
'download': d.getFullYear()+"-"+("0" + d.getMonth()).slice (-2)+"-"+("0" + d.getDate()).slice (-2)+"_"+("0" + d.getHours()).slice (-2)+"-"+("0" + d.getMinutes()).slice (-2)+"-"+("0" + d.getSeconds()).slice (-2)+'.csv'
});
}
}
在“myClass”类中添加哈希映射之前,一切正常。然后为以下Json输入(朋友是一个hashMap)
val myInstance = (new Gson()).fromJson(t, classOf[myClass])
然后我在“firstname”属性中收到以下错误,如下所示。有谁有想法吗?非常感谢你!
{"pId":"P:12345","name":"Dan Brown","friends":{"{\"firstname\":\"John\",\"lastname\":\"Smith\"}":1.0}}
这是myClass类:
15/07/29 08:43:05 ERROR Executor: Exception in task 0.0 in stage 0.0 (TID 0)
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 51
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:176)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40)
at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:186)
at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:145)
这是myName类:
public final class myClass extends implements Serializable {
private static final long serialVersionUID = 11271827L;
private String pId;
private String name;
private List<MyPet> pets = new ArrayList<MyPet>();
private Map<MyName, Double> friends = new HashMap<MyName, Double>();
:
//some getter/setter here
}
答案 0 :(得分:0)
在json中,map的键应该是string。在您的情况下,您使用MyName
作为密钥。所以json解析器使用MyName#toString()
转换为字符串。
我的建议是正确的MyName#toString()
实现,并在MyName类中提供静态方法MyName valueOf(String)
例如:
class MyName{
private String firstName;
private String lastName;
// getters and setters
@Override
public String toString(){
return firstName+" "+lastName;
}
public static MyName valueOf(String str){
int space = str.lastIndexOf(' ');
if(space==-1)
throw new IllegalArgumentException();
MyName myName = new MyName();
myName.setFirstName(str.subString(0, space));
myName.setLastName(str.subString(space+1));
return myName;
}
}
此处valueOf
和toString
实施应兼容。
上述代码假定lastName
答案 1 :(得分:0)
你在做什么是一个坏主意。不要在JSON名称中提供表示为String的复杂对象结构。
尽管如此,这仍然是一个解决方案。提供并注册自定义JsonDeserializer
Gson gson = new GsonBuilder().registerTypeAdapter(MyName.class, new KeyDeserializer()).create();
...
class KeyDeserializer implements JsonDeserializer<MyName> {
private Gson gson = new Gson();
@Override
public MyName deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
return gson.fromJson(json.getAsString(), MyName.class);
}
}
JsonElement
将包含JSON字符串(它将是JsonPrimitive
)。在其上调用getAsString
将返回Java String
值
{"firstname":"John","lastname":"Smith"}
然后,我们使用单独的Gson
实例将其反序列化为具有默认行为的MyName
实例。我们需要第二个Gson
实例,因为原始实例已经注册KeyDeserializer
进行自定义反序列化。