복붙노트

[SPRING] RoboSpice는 OrmLite를 사용하여 JSON 배열을 유지합니다.

SPRING

RoboSpice는 OrmLite를 사용하여 JSON 배열을 유지합니다.

저는 RoboSpice를 Android 용 Spring과 함께 사용하고 있으며 JSON 배열을 OrmLite로 유지하려고합니다. 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)를 변경할 때; to 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 배열을 처리하는 방법에 대해 알고 싶습니다.

해결법

  1. ==============================

    1.이 문제를 해결하기위한 방법을 찾았습니다. 개체 배열을 보유하고있는 추가 결과 개체를 추가했습니다. 물론 이것은 JSON을 조작 ​​할 수있는 경우에만 가능합니다. 내 모델에 쓸모없는 클래스를 도입했기 때문에 여전히 만족스럽지 않습니다.

    이 문제를 해결하기위한 방법을 찾았습니다. 개체 배열을 보유하고있는 추가 결과 개체를 추가했습니다. 물론 이것은 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
        ...
    }
    
  2. ==============================

    2.나는 나를 위해 일하는 길을 발견했다. 나는 내 아들을 바꾸지 않았다.

    나는 나를 위해 일하는 길을 발견했다. 나는 내 아들을 바꾸지 않았다.

    @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);
                }
            }
    
        }
    
    
    }
    
  3. ==============================

    3.오늘이 모든 것을 고민하고 마침내 JSON을 수정하지 않고 Robospice Spring Android를 사용하여 SQLite 데이터베이스에 JSON 배열을 저장하는 방법을 알아 냈습니다.

    오늘이 모든 것을 고민하고 마침내 JSON을 수정하지 않고 Robospice Spring Android를 사용하여 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 단계:

    안드로이드 측에서 2 개의 클래스를 생성해야합니다.

    하나는 배열에서 저장하려는 일반 객체입니다. 내 경우에는 "Post"라는 객체가 있고 내 서버는 "Post"의 배열을 반환합니다.

    @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;
    

    다른 객체는 배열을 감싸는 래퍼 객체가 될 것이고, 저는 광산 "EmbedPost"라고 부릅니다.

    @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"
    }
    ]}
    

    Uipko가 자신의 솔루션에서 사용한 것과 매우 유사한 JSON 문자열입니다.

    { 
        "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;
        }
    
    }
    

    ORMite가 둘 다 유지하지 않으면 ORMLite가 작업을 수행 할 수 없으므로 EmbedPost.class와 Post.class를 모두 classCollection에 추가하십시오. 당신은 당신이 당신의 객체를 썼을 때 ForeignKeys를 사용했고,이 외래 키들은 무언가에 묶여야만하므로, 두 클래스 모두 유지되어야합니다.

    문제가 생기면 logcat을 사용해보십시오. 오류 메시지뿐만 아니라 모든 메시지를 읽어야 할 수도 있습니다. 모든 logcat 메시지를 읽는 방법을 보려면 내 게시물을 참조하십시오.

    Ormlite를 통해 데이터베이스에 ArrayList를 확장 한 Robospice 저장 객체

  4. from https://stackoverflow.com/questions/15835415/robospice-persist-json-array-with-ormlite by cc-by-sa and MIT license