我正在使用RoboSpice和Spring for Android,并希望使用OrmLite保留JSON对象数组。 GSON用于JSON编组。使用默认缓存,一切都按预期工作。但OrmLite似乎不喜欢对象数组。
这是JSON的简化版本:
[{"id": 1, "title": "Test 1"},{"id": 2, "title": "Test 3"},{"id": 3, "title": "Test 3"}]
我想在以下对象中坚持这一点:
@DatabaseTable
public class Foo {
@DatabaseField(id = true)
private int id;
@DatabaseField
private String title;
// getters and setters
...
}
基于RoboSpice OrmLite示例,我创建了以下GsonSpringAndroidSpiceService类来添加OrmLite CacheManager。这就是问题的出发点。
public class CustomGsonSpringAndroidSpiceService extends GsonSpringAndroidSpiceService
{
@Override
public CacheManager createCacheManager(Application application)
{
// add persisted classes to class collection
List<Class<?>> classCollection = new ArrayList<Class<?>>();
classCollection.add(Foo.class);
// init
CacheManager cacheManager = new CacheManager();
cacheManager.addPersister(new InDatabaseObjectPersisterFactory(
application, new RoboSpiceDatabaseHelper(
application, "database.db", 1), classCollection));
return cacheManager;
}
}
这会导致以下错误:
RequestProcessor.java:174(22356): java.lang.RuntimeException: Class [Lcom.example.model.Foo; is not handled by any registered factoryList
当我将classCollection.add(Foo.class);
更改为classCollection.add(Foo[].class);
时
我收到以下错误:
RequestProcessor.java:174(22601): 14:42:23.112 pool-5-thread-1 An unexpected error occured when processsing request CachedSpiceRequest [requestCacheKey=foo, cacheDuration=-1, spiceRequest=com.example.app.FooRequest@4055df40]
RequestProcessor.java:174(22601): java.lang.IllegalArgumentException: No fields have a DatabaseField annotation in class [Lcom.example.app.model.Foo;
任何人都知道如何使用OrmLite CacheManager处理JSON数组?
答案 0 :(得分:6)
我找到了解决这个问题的方法。我添加了一个额外的结果对象,它保存了对象数组。当然,只有在你能够操纵JSON时才有可能。仍然不满意这一点,因为我在我的模型中引入了一个无用的类。
所以我的JSON看起来像:
{
"id": 1,
"result":[{"id": 1, "title": "Test 1"},{"id": 2, "title": "Test 3"},{"id": 3, "title": "Test 3"}]
}
我添加了以下类来保存JSON结果:
@DatabaseTable
public class FooResult {
@DatabaseField(id = true)
private int id;
@ForeignCollectionField(eager = false)
private Collection<Foo> result;
// getters and setters
...
}
还添加了Foo类的外来关系:
@DatabaseTable
public class Foo {
@DatabaseField(id = true)
private int id;
@DatabaseField
private String title;
@DatabaseField(foreign = true)
private FooResult result;
// getters and setters
...
}
答案 1 :(得分:3)
我找到了适合我的方式。我没有改变我的json。
@DatabaseTable(tableName = SampleContract.Contributor.TABLE)
public class Contributor {
@DatabaseField(generatedId = true, columnName = SampleContract.Contributor._ID)
private int id;
@DatabaseField(columnName = SampleContract.Contributor.LOGIN)
public String login;
@DatabaseField(columnName = SampleContract.Contributor.CONTRIBUTIONS)
public int contributions;
@DatabaseField(foreign = true)
private ContributorsResult result;
@SuppressWarnings("serial")
@DatabaseTable(tableName = "contributor_list")
public static class ContributorsResult extends ArrayList<Contributor> {
@DatabaseField(id = true)
private int id = 0;
@ForeignCollectionField(eager = false)
private Collection<Contributor> result = this;
public Collection<Contributor> getResult() {
return result;
}
public void setResult(Collection<Contributor> result) {
if (result != null) {
this.clear();
this.addAll(result);
}
}
}
}
答案 2 :(得分:0)
今天我一直在努力解决这个问题,最后想出了如何使用Robospice Spring Android将JSON数组保存到SQLite数据库中,而无需修改JSON。
这是我从服务器返回的帖子JSON数组:
[
{
"id": "5573547af58cd75df03306cc",
"name": "Simon",
"postheader": "First Post"
},
{
"id": "55735475f58cd75df03306cb",
"name": "Tyron",
"postheader": "Second Post"
}
]
这与此问题中的JSON类似:
[{"id": 1, "title": "Test 1"},{"id": 2, "title": "Test 3"},{"id": 3, "title": "Test 3"}]
第1步:
你需要在android端创建2个类。
一个是您要从数组中保存的普通对象。就我而言,我有一个名为&#34; Post&#34;我的服务器返回一个&#34; Post&#34;。
的数组@DatabaseTable(tableName = "post")
@JsonIgnoreProperties(ignoreUnknown = true)
public class Post implements Serializable {
@DatabaseField(id = true)
private String id;
@DatabaseField
private String name;
@DatabaseField
private String postheader;
@DatabaseField(foreign = true,foreignAutoCreate = true,foreignAutoRefresh = true)
private EmbedPost posts;
另一个对象将是一个包装数组的包装器对象,我称之为&#34; EmbedPost&#34;。
@DatabaseTable
public class EmbedPost implements Serializable {
@DatabaseField(allowGeneratedIdInsert=true, generatedId=true)
private int ID;
@ForeignCollectionField(eager = false)
private Collection<Post> posts;
通过在我的EmbedPost类中定义一个名为ID的int,我有效地创建了一个对象,如果我转换为JSON,它将如下所示:
{"id": 1, "posts": [
{
"id": "5573547af58cd75df03306cc",
"name": "Simon",
"postheader": "First Post"
},
{
"id": "55735475f58cd75df03306cb",
"name": "Tyron",
"postheader": "Second Post"
}
]}
这实际上是一个JSON字符串,看起来非常类似于Uipko在其解决方案中使用的字符串。
{
"id": 1,
"result":[{"id": 1, "title": "Test 1"},{"id": 2, "title": "Test 3"},{"id": 3, "title": "Test 3"}]
}
第2步:
现在使用SpringAndroidSpiceService将其保留。
public class AndroidSpiceService extends SpringAndroidSpiceService {
private static final int WEBSERVICES_TIMEOUT = 10000;
@Override
public CacheManager createCacheManager( Application application ) {
CacheManager cacheManager = new CacheManager();
List< Class< ? >> classCollection = new ArrayList< Class< ? >>();
// add persisted classes to class collection
classCollection.add(EmbedPost.class);
classCollection.add( Post.class );
// init
RoboSpiceDatabaseHelper databaseHelper = new RoboSpiceDatabaseHelper( application, "sample_database.db", 3);
InDatabaseObjectPersisterFactory inDatabaseObjectPersisterFactory = new InDatabaseObjectPersisterFactory( application, databaseHelper, classCollection );
cacheManager.addPersister( inDatabaseObjectPersisterFactory );
return cacheManager;
}
@Override
public RestTemplate createRestTemplate() {
RestTemplate restTemplate = new RestTemplate();
// set timeout for requests
HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
httpRequestFactory.setReadTimeout( WEBSERVICES_TIMEOUT );
httpRequestFactory.setConnectTimeout( WEBSERVICES_TIMEOUT );
restTemplate.setRequestFactory( httpRequestFactory );
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
final List<HttpMessageConverter< ? >> listHttpMessageConverters = restTemplate.getMessageConverters();
listHttpMessageConverters.add( mappingJackson2HttpMessageConverter );
restTemplate.setMessageConverters( listHttpMessageConverters );
return restTemplate;
}
}
确保将EmbedPost.class和Post.class都添加到classCollection中,因为如果没有两者都持久化,ORMLite就无法完成它的工作。在编写对象时使用了ForeignKeys,这些外键必须与某些东西绑定,因此这两个类必须保持不变。
如果遇到麻烦,请尝试使用logcat来解决问题。您可能必须阅读所有消息,而不仅仅是错误消息。 请参阅我的帖子,了解如何阅读所有logcat消息:
Robospice storing object that extends ArrayList in database via Ormlite