【发布时间】:2014-04-27 07:31:30
【问题描述】:
我已经修改了 Azure 移动服务中我的一个表的更新脚本,以接收一个包含一组对象的对象,并使用 MSSQL 对象更新与这些对象相关的 SQL 记录。效果很好,但我希望我的更新脚本将更新的对象列表返回给客户端。问题是我似乎无法将 JSON 对象返回给客户端并将其反序列化为正确的 StoryList 对象,而不会在客户端上遇到“com.google.gson.JsonSyntaxException:java.lang.IllegalStateException”。
我花了几个小时试图弄清楚这一点,但仍然不知道我在这里做错了什么。我错过了什么吗?
编辑:这是客户端阻塞的 JSON:
{"id":"arandomid",
"stories":
[
{"id":"7EC413C3-17A8-410A-A394-ABF334364226",
"__createdAt":"2014-03-31T22:22:14.398Z",
"__updatedAt":"2014-04-28T01:43:27.484Z",
"__version":"AAAAAAAACf4=",
"title":"remove a user story",
"relativepriority":11,
"estimate":7,
"assignedto":"David",
"sprintid":"E51B4E0D-23C7-4695-BD9B-71E34A0BF5B5",
"sprintphase":1},
{"id":"99890AFE-13C2-4E1A-8376-B501CB07080D",
"__createdAt":"2014-03-31T22:26:35.160Z",
"__updatedAt":"2014-04-28T01:43:27.484Z",
"__version":"AAAAAAAACf0=",
"title":"view user story list",
"relativepriority":10,
"estimate":15,
"assignedto":"Michael",
"sprintid":"E51B4E0D-23C7-4695-BD9B-71E34A0BF5B5",
"sprintphase":1}
]
}
这里是更新脚本:
var storiesToUpdate;
var returnItem;
function update(item, user, request) {
returnItem = item;
storiesToUpdate = JSON.parse(item.stories);
if(storiesToUpdate.length > 0){
var sql = "UPDATE UserStory SET relativepriority = CASE id ";
for(var i = 0; i < storiesToUpdate.length; ++i){
sql+= ("WHEN '" + storiesToUpdate[i].id + "' THEN " + storiesToUpdate[i].relativepriority + " ");
}
sql+="END ";
sql+="WHERE ";
for(var i = 0; i < storiesToUpdate.length; ++i){
if(i > 0) sql+= "OR ";
sql+= ("(id = '" + storiesToUpdate[i].id + "') ");
}
mssql.query(sql,{
success: function(connection){
var sql2 = 'SELECT * from UserStory '
sql2+="WHERE ";
for(var i = 0; i < storiesToUpdate.length; ++i){
if(i > 0) sql2+= "OR ";
sql2+= ("(id = '" + storiesToUpdate[i].id + "') ");
}
mssql.query(sql2,{
success:function(results){
console.log("results: " + results);
var returnObject = {};
returnObject["id"]="arandomid";
returnObject["stories"]=results;
console.log("return object: " + returnObject);
request.respond(statusCodes.OK, returnObject);
},
error: function(err){
console.log("Update ok, but subsequent read failed: " + err);
request.respond(err);
}
});
},
error: function(err) {
console.log("fail on open: " + err);
request.respond(err);
}
});
}
else{
request.respond();
}
}
这是在 Android 应用中被序列化/反序列化的类:
public class StoryList {
@com.google.gson.annotations.SerializedName("id")
private String mId;
@com.google.gson.annotations.SerializedName("stories")
ArrayList<UserStory> mStories;
public StoryList(){
}
public String getId() {
return mId;
}
public final void setId(String id) {
mId = id;
}
public void setStories(ArrayList<UserStory> stories){
this.mStories = stories;
}
public ArrayList<UserStory> getStories(){
return mStories;
}
}
这是我注册的 CollectionSerializer 类,用于在单个查询中发送并希望返回对象集合:
public class CollectionSerializer<E> implements
JsonSerializer<Collection<E>>, JsonDeserializer<Collection<E>>{
public JsonElement serialize(Collection<E> collection, Type type,
JsonSerializationContext context) {
JsonArray result = new JsonArray();
for(E item : collection){
result.add(context.serialize(item));
}
JsonPrimitive retVal = new JsonPrimitive(result.toString());
Log.i("CollectionSerializer.Serialize", retVal.getAsString());
return retVal;
}
@SuppressWarnings("unchecked")
public Collection<E> deserialize(JsonElement element, Type type,
JsonDeserializationContext context) throws JsonParseException {
Log.i("CollectionSerializer.Deserialize", element.getAsString());
JsonArray items = (JsonArray) new JsonParser().parse(element.getAsString());
ParameterizedType deserializationCollection = ((ParameterizedType) type);
Type collectionItemType = deserializationCollection.getActualTypeArguments()[0];
Collection<E> list = null;
try {
list = (Collection<E>)((Class<?>) deserializationCollection.getRawType()).newInstance();
for(JsonElement e : items){
list.add((E)context.deserialize(e, collectionItemType));
}
} catch (InstantiationException e) {
throw new JsonParseException(e);
} catch (IllegalAccessException e) {
throw new JsonParseException(e);
}
return list;
}
}
最后,这里是我实际启动查询以进行更新的地方:
@Override
public void onStoryListReorder(int phaseNumber){
float newRelPriority = 10;
ArrayList<UserStory> phaseStoryList = mPhaseStories.get(phaseNumber);
for (UserStory s : phaseStoryList){
s.setRelativePriority(newRelPriority++);
}
StoryList storylist = new StoryList();
storylist.setStories(phaseStoryList);
storylist.setId("blahblahblah");
MobileServiceTable<StoryList> storyListTable = mClient.getTable("UserStory",StoryList.class);
storyListTable.update(storylist, new TableOperationCallback<StoryList>(){
public void onCompleted(StoryList entity,
Exception exception,
ServiceFilterResponse response){
if (exception == null){
//This is where I want to update the client's list of stories to match Azure's list.
}
else {
createAndShowDialog(exception, "Error on updating: "+exception.toString());
}
}
});
}
【问题讨论】:
-
com.google.gson.JsonSyntaxException 当 Gson 尝试读取(或写入)格式错误的 JSON 元素时引发此异常
-
对,但是我需要在我的脚本中做些什么不同的事情来使 JSON 不会出现格式错误?
-
老实说...您在这里发布了很多代码...但没有一个真正让我们能够帮助您。只是看了一眼,尽管您似乎不太可能需要任何类型的自定义反序列化,而且您似乎只返回一个 JSON 对象,但正试图将其视为一个集合。首先发布一个返回到您的应用的 JSON 示例。
-
是的,忘记包含 JSON 本身 :) 我刚刚添加了那个。请参阅我上面的编辑。关于 CollectionSerializer,它与这里建议的发送对象 ArrayList 的方式基本相同:hashtagfail.com/post/44606137082/…
标签: javascript android node.js gson azure-mobile-services