2017-08-14 262 views
3

我已经构建了一个RetroFitService以返回一些对象。在MainActivity中,我通过简单的按钮点击来调用服务。我似乎正在获得某种对象,但我不觉得它实际上是从我指定的REST API返回的。它显示了在调试器,但它的属性是空的:Retrofit对象返回为空

bFetch.setOnClickListener(v -> { 
v.startAnimation(AnimationUtils.loadAnimation(this, R.anim.image_click)); 
RetrofitService service = ServiceFactory.createRetrofitService(RetrofitService.class, RetrofitService.SERVICE_ENDPOINT); 
service.getPosts() 
.subscribeOn(Schedulers.newThread()) 
.observeOn(AndroidSchedulers.mainThread()) 
.subscribe(new Subscriber <Post>() { 
    @Override 
    public final void onCompleted() { 
    Log.e("RetrofitService", "Retrofit Request Completed!"); 
    } 

    @Override 
    public final void onError(Throwable e) { 
    Log.e("RetrofitService", e.getMessage()); 
    } 

    @Override 
    public final void onNext(Post post) { 
    if (post != null) { 
    // TODO: Some object is returned but its properties are null 
    Log.e("RetrofitService", "Returned objects: " + post); 
    Log.e("RetrofitService", "Object Id: " + post.getObjectId()); 
    mCardAdapter.addData(post); 
    } else { 
    Log.e("RetrofitService", "Object returned is null."); 
    } 

    } 

}); 

}); 

} 

enter image description here

服务:

public interface RetrofitService { 

String SERVICE_ENDPOINT = "https://parseapi.back4app.com/"; 

@Headers({ 
    "X-Parse-Application-Id: asdf", 
    "X-Parse-REST-API-Key: asdf" 
}) 
@GET("/classes/Post") 
Observable <Post> getPosts(); 

/*curl -X GET \ 
     -H "X-Parse-Application-Id: asdf" \ 
     -H "X-Parse-REST-API-Key: asdf" \ 
https://parseapi.back4app.com/classes/Post*/ 

} 

的卷曲工作得很好。我没有收到任何错误。可能会出现什么问题? ?难道我@GET方法不正确莫名其妙`

完成,这里是的ServiceFactory类:

public class ServiceFactory { 

    /** 
    * Creates a retrofit service from an arbitrary class (clazz) 
    * @param clazz Java interface of the retrofit service 
    * @param endPoint REST endpoint url 
    * @return retrofit service with defined endpoint 
    */ 
    public static <T> T createRetrofitService(final Class<T> clazz, final String endPoint) { 
     final RestAdapter restAdapter = new RestAdapter.Builder() 
       .setEndpoint(endPoint) 
       .build(); 
     T service = restAdapter.create(clazz); 

     return service; 
    } 
} 

而且我的build.gradle,因为我知道有所有不同的不一致改装版本:

dependencies { 

    compile fileTree(dir: 'libs', include: ['*.jar']) 
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 
     exclude group: 'com.android.support', module: 'support-annotations' 
    }) 
    compile 'com.android.support:appcompat-v7:25.3.1' 
    compile 'com.android.support.constraint:constraint-layout:1.0.2' 
    testCompile 'junit:junit:4.12' 

    /* ReactiveX */ 
    compile 'io.reactivex:rxjava:1.0.17' 
    compile 'io.reactivex:rxandroid:0.23.0' 

    /* Retrofit */ 
    compile 'com.squareup.retrofit:retrofit:1.9.0' 

    /* OkHttp3 */ 
    compile 'com.squareup.okhttp3:okhttp:3.8.1' 

    /* RecylerView */ 
    compile 'com.android.support:recyclerview-v7:25.3.1' 

    /* CardView */ 
    compile 'com.android.support:cardview-v7:25.3.1' 

    /* Parse */ 
    compile 'com.parse:parse-android:1.13.0' 

} 

Post类:

public class Post implements Serializable { 

    private static final String CLASS_NAME = "Post"; 

    private String objectId; 
    private String text; 

    public Post(String objectId) { 
     this.setObjectId(objectId); 
    } 

    public static String getClassName() { 
     return CLASS_NAME; 
    } 

    public String getObjectId() { 
     return objectId; 
    } 

    private void setObjectId(String objectId) { 
     this.objectId = objectId; 
    } 

    public String getText() { 
     return text; 
    } 

    public void setText(String text) { 
     this.text = text; 
    } 

卷曲响应:

>  https://parseapi.back4app.com/classes/Post/ 
    % Total % Received % Xferd Average Speed Time Time  Time Current 
           Dload Upload Total Spent Left Speed 
100 259 100 259 0  0 360  0 --:--:-- --:--:-- --:--:-- 395{"results":[{"objectId":"ktEfgr1pFt","text":"Hello World.","createdAt":"2017-08-14T14:07:52.826Z","updatedAt":"2017-08-14T14:07:52.826Z"},{"objectId":"Mmh8l9gjCk","text":"Hello?","createdAt":"2017-08-14T15:19:01.515Z","updatedAt":"2017-08-14T15:19:03.743Z"}]} 

最后更新:我改变RetrofitServiceonNext()方法通入CardAdapter,尽管这里未示出和超过的范围题。

@Override 
public final void onNext(PostResponse postResponse) { 
if (postResponse != null) { 
    // TODO: Some object is returned but its properties are null 
    Log.e("RetrofitService", "Objects successfully added to RecyclerView Adapter."); 
    Log.e("RetrofitService", "Returned objects: " + postResponse.getResults()); 
    Log.e("RetrofitService", "Text " + postResponse.getResults().get(0).getText()); 

    mCardAdapter.addData(postResponse); 
    // 
} else { 
    Log.e("RetrofitService", "Object returned is null."); 
} 

} 
+0

好像你正在试图获取这是通过解析SDK创建的对象。确保Post类的数据结构与端点返回的内容匹配(例如,使用String)。 而顺便说一句,我会掩盖的问题的网址和凭据。 –

+1

我用Post对象更新了我的问题。我真的没有看到它的问题... – santafebound

+0

你能否也提供来自 的json响应curl -X GET -H“X-Parse-Application-Id:asdf”-H“X-Parse-REST-API -Key:asdf“https://parseapi.back4app.com/classes/Post –

回答

2

尝试使用下面的类中RetrofitService

@GET("/classes/Post") 
Observable <PostResponse> getPosts(); 

PostResponse包装类

public class PostResponse { 
    private List<Post> results; 

    public List<Post> getResults() { 
     return results; 
    } 

    public void setResults(List<Post> results) { 
     this.results = results; 
    } 
} 
+0

你们让我很难回报这个问题。两个答案都有帮助。是的,我确实必须包装我在这里提供的课程中返回的列表。 – santafebound

+0

我认为Torsten比我更值得奖励。他先回答:) –

+1

很酷,但我认为答案还应该包括关于尾部斜线的部分,以便让其他人获得那一点。干杯。 – santafebound

1

根据您的问题您收到不是一个单一对象的更新,而是一个对象与收集的Post对象。

所以,你需要增加一个类:

public class Results { 
    List<Post> results = ArrayList<>() 
} 

然后更新您的API接口方法返回Observable<Results>

Observable <Results> getPosts(); 

及认购里面你终于可以与访问Result对象results字段,包含Post对象的集合。


,稍有差错的是,你的终点基本URL已斜线:

String SERVICE_ENDPOINT = "https://parseapi.back4app.com/"; 

同时您的API方法在路径的开始已经削减:

@GET("/classes/Post") 
Observable <Post> getPosts(); 

据我记得与改造,你应该有终点地址的尾部斜线或在API方法中开始斜杠,否则这可能不会w ork正确。

这应该是正确的:

String SERVICE_ENDPOINT = "https://parseapi.back4app.com"; // No slash here 
@GET("/classes/Post") // Keep slash here, or vice verse 
Observable<Results> getPosts(); 

只是一些对你的依赖节发表了评论:

是否有您使用io.reactivex:rxandroid版本0.23.0而最新的稳定是1.2.1什么特殊的原因吗?

你不需要io.reactivex:rxjava:1.0.17依赖,如改装1.9.0已经取决于rxjava 1.0.0

+0

谢谢。你对最后的斜线是正确的。我清理了我的依赖关系。我只使用0.23.0,因为这是我在之前的项目中使用它的地方(在稍微不同的实现中)。看起来像改造最近经历了很多变化。不幸的是,我仍然得到空对象属性。也许这是因为我正在返回一个列表,而不是像Torsten所指出的那样处理它。 – santafebound

+0

根据我的Monitor的说法,似乎“RetrofitService.getPosts:URL路径”classes/Post“必须以'/'开始。 – santafebound

+0

@santafebound你发布了json响应正文,我更新了我的答案。您将包含在结果字段内的另一个对象的Post对象的集合分解为单个Post对象。这是真正的错误。不是一个尾随的斜线。 –