我正在开发一个使用 Google App-Engine 来存储和管理应用程序数据的 Android 应用程序。不幸的是,我遇到了一个我似乎无法解决的问题。
当用户创建一个新帐户时,会为他们创建一个新的“项目”。该项目包含任务,这些任务存储在 Project 类的一个 ArrayList 中。因此,在项目类的构造函数中,所有内容都被实例化,并且任务是使用 Gson2.2.2 从带有 Json 格式数据的文本文件创建的。
所有这一切都很好,如果我在 appengine 管理控制台中查看数据存储查看器,一切看起来都很好。创建帐户后,用户立即登录,当用户登录时,需要将任务发送到 Android 客户端。这就是它变得奇怪的地方。将任务序列化回 Json 格式时,它们似乎未初始化。所有字符串字段都是空的,并且整数都设置为 0,但是正在序列化正确数量的任务,因此会填充列表。这个问题一直存在,直到我在 GAE 中手动关闭了实例。当它通过新请求重新启动时,数据会正确序列化为 Json 格式,并且一切正常。显然这不好,每次新用户创建帐户时,我都不能让服务器关闭它的实例,只是为了能够为他们提供正确的数据。所以,请帮我解决这个问题。我已经为此苦苦挣扎了一段时间。下面是准确重现问题的代码。
public class CreateData extends HttpServlet{
public void doGet(HttpServletRequest req, HttpServletResponse resp){
if(req.getParameter("name").length() > 1){
PersistenceManager pm = PMF.get().getPersistenceManager();
User u = new User(req.getParameter("name"));
pm.makePersistent(u);
pm.close();
try {
resp.getWriter().print("User created with name "+req.getParameter("name"));
} catch (IOException e) {
e.printStackTrace();
}
}else if(req.getParameter("name").length() <= 1){
try {
resp.getWriter().print("Please supply a name with at least 2 characters");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
try {
resp.sendError(400);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
用户类
public class User {
public @interface Skip {
// Field tag only annotation
}
@PrimaryKey
@Persistent
private String name;
@Persistent
private ArrayList<DataType> data;
public User(String name) {
this.name = name;
data = new ArrayList<DataType>();
createDataFromJSON();
}
public String getDatasAsJSON(){
Gson gson = new GsonBuilder().setExclusionStrategies(new MyExclusionStrategy(Key.class)).create();
Type taskType = new TypeToken<List<DataType>>(){}.getType();
String json = gson.toJson(this.data, taskType);
return json;
}
public void createDataFromJSON() {
FileReader fr = null;
try {
fr = new FileReader(new File("WEB-INF/defaults.json"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if (fr != null) {
Type taskType = new TypeToken<List<DataType>>(){}.getType();
data = new Gson().fromJson(fr, taskType);
}
}
public class MyExclusionStrategy implements ExclusionStrategy {
private final Class<?> typeToSkip;
private MyExclusionStrategy(Class<?> typeToSkip) {
this.typeToSkip = typeToSkip;
}
public boolean shouldSkipClass(Class<?> clazz) {
return (clazz == typeToSkip);
}
public boolean shouldSkipField(FieldAttributes f) {
return f.getAnnotation(Skip.class) != null;
}
}
}
数据类型类
public class DataType {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key key;
@Persistent
private String name;
@Persistent
private int points;
@Persistent
private int unique;
public DataType() {
}
public DataType(String name, int points, int unique){
this.name = name;
this.points = points;
this.unique = unique;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPoints() {
return points;
}
public void setPoints(int points) {
this.points = points;
}
public int getUnique() {
return unique;
}
public void setUnique(int unique) {
this.unique = unique;
}
}
用于获取数据的 Servlet
public class GetData extends HttpServlet{
public void doGet(HttpServletRequest req, HttpServletResponse resp){
String name = req.getParameter("name");
PersistenceManager pm = PMF.get().getPersistenceManager();
User u = null;
try{
u = pm.getObjectById(User.class, name);
}catch(JDOObjectNotFoundException e){
try {
resp.sendError(404);
} catch (IOException e1) {
e1.printStackTrace();
}
}
if(u != null){
String response = u.getDatasAsJSON();
try {
resp.getWriter().print(response);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
和 JSON 数据
[
{
"name": "Hug",
"unique": 1,
"points": 20
},
{
"name": "Tug",
"unique": 2,
"points": 40
},
{
"name": "Rug",
"unique": 3,
"points": 50
},
{
"name": "Jug",
"unique": 4,
"points": 100
},
{
"name": "Smug",
"unique": 5,
"points": 20
}
]
因此,创建一个名为“Arne”的新用户可以正常工作,并且在 HDR 中创建对象。以 Json 的形式从数据存储中请求返回对象会产生此响应
[{"points":0,"unique":0},{"points":0,"unique":0},{"points":0,"unique":0},{"points":0,"unique":0},{"points":0,"unique":0}]
在重新启动服务器实例时,相同的请求会给出此响应
[{"name":"Hug","points":20,"unique":1},{"name":"Tug","points":40,"unique":2},{"name":"Rug","points":50,"unique":3},{"name":"Jug","points":100,"unique":4},{"name":"Smug","points":20,"unique":5}]
很抱歉这篇文章很长,但希望有人能够向我指出我做错了什么。提前谢谢了!最好的问候, 伊瓦尔