2017-08-17 109 views
0

我试图让onResponse()在我的回调中执行。出于某种原因,即使服务器正在返回一个200代码,我也会收到我的数据。Retrofit:onFailure().....预计BEGIN_OBJECT,但是STRING

我不确定必须做些什么onResponse才能正确执行,因此我可以解析JSON并将对象添加到列表视图。

相关片段: -

public class ActivePostFragment extends ListFragment implements AdapterView.OnItemClickListener, OnClickListener{ 
    private ProgressBar progress; 
    private Button btn_newPost; 
    private RecyclerView recyclerView; 
    private MyItemRecyclerViewAdapter mAdapter; 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.fragment_activepost,container,false); 
     initViews(view); 
     int uIdValue = getArguments().getInt("userID"); 
     Log.d(Constants.TAG, String.valueOf(uIdValue)); 
     progress.setVisibility(View.VISIBLE); 
     loadPostsProcess(uIdValue); 
     RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity().getApplicationContext()); 
     recyclerView.setLayoutManager(mLayoutManager); 
     recyclerView.setItemAnimator(new DefaultItemAnimator()); 
     return view; 
    } 
    @Override 
    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { 
    } 
    @Override 
    public void onClick(View v){ 
     switch (v.getId()){ 
      case R.id.newPost: 
       goToNewPost(); 
       break; 
     } 
    } 
    private void initViews(View view){ 
     btn_newPost = (Button) view.findViewById(R.id.newPost); 
     recyclerView = (android.support.v7.widget.RecyclerView) view.findViewById(R.id.recyclerView); 
     btn_newPost.setOnClickListener(this); 
     progress = (ProgressBar)view.findViewById(R.id.activePostProgress); 
    } 
    private void loadPostsProcess(int uIdValue) { 
     HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); 
     interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); 
     OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build(); 
     Gson gson = new GsonBuilder() 
       .setLenient() 
       .create(); 
     Retrofit retrofit = new Retrofit.Builder() 
       .baseUrl(Constants.BASE_URL) 
       .client(client) 
       .addConverterFactory(GsonConverterFactory.create(gson)) 
       .build(); 
     RequestInterface requestInterface = retrofit.create(RequestInterface.class); 
     User user = new User(); 
     ServerRequest request = new ServerRequest(); 
     request.setOperation(Constants.RETRIEVE_ALL_OPERATION); 
     request.setUser(user); 
     final Call<PostsServerResponse> response = requestInterface.postsByUser(uIdValue); 
      response.enqueue(new Callback<PostsServerResponse>() { 
       @Override 
       public void onResponse(Call<PostsServerResponse> call, retrofit2.Response<PostsServerResponse> response) { 
        PostsServerResponse resp = response.body(); 
        String jsonServerPosts = resp.getPosts(); 

        Type listType = new TypeToken<ArrayList<Post>>(){}.getType(); 
        final ArrayList<Post> jsonArrayList = new Gson().fromJson(jsonServerPosts, listType); 
        Log.d(Constants.TAG, jsonArrayList.toString()); 

        RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity().getApplicationContext()); 
        recyclerView.setLayoutManager(mLayoutManager); 
        recyclerView.setItemAnimator(new DefaultItemAnimator()); 
        recyclerView.setAdapter(new MyItemRecyclerViewAdapter(jsonArrayList, getActivity())); 
        progress.setVisibility(View.INVISIBLE); 
       } 
       @Override 
       public void onFailure(Call<PostsServerResponse> call, Throwable t) { 
        Log.d(Constants.TAG, "Retrofit: onResponse not called, onFailure called instead... "); 
        Log.d(Constants.TAG, t.getStackTrace().toString()); 
        Log.d(Constants.TAG, t.getMessage()); 
        Snackbar.make(getView(), t.getLocalizedMessage(), Snackbar.LENGTH_INDEFINITE).show(); 
        progress.setVisibility(View.INVISIBLE); 
       } 
      }); 
    } 
    private void goToViewPost(){ 
    } 
    private void goToNewPost(){ 
     Fragment newPost = new NewPostFragment(); 
     FragmentTransaction ft = getFragmentManager() 
       .beginTransaction(); 
     ft.replace(R.id.fragment_frame, newPost); 
     ft.commit(); 
    } 
} 

请求接口: -

公共接口RequestInterface {

@POST("index.php/") 
Call<LoginServerResponse> operation(@Body ServerRequest request); 

@GET("activePosts.php/") 
Call<PostsServerResponse> postsByUser(@Query("uid") int userID);} 

ServerResponse类:

public class PostsServerResponse { 
    private String result; 
    private String message; 
    private String posts; 
    public String getResult() { 
     return result; 
    } 
    public String getMessage() { 
     return message; 
    } 
    public String getPosts() { 
     return posts; 
    } 
} 

PHP代码: -

require_once 'Functions.php'; 
$fun = new Functions(); 

if ($_SERVER['REQUEST_METHOD'] == 'GET'){ 
    $queryUserID = htmlspecialchars($_GET["uid"]); 
    echo 'url query ID is: '.$queryUserID.'. '; 
    echo $fun -> getPosts($queryUserID); 

的functions.php:

public function getPosts($queryUserID){ 
     $db = $this -> db; 

    if ($db -> postsExist($queryUserID)){ 
    $result = $db -> getUserPosts($queryUserID); 
    $response["result"] = "Success. "; 
    $response["message"] = "Posts found. "; 
    // might need to handle the formatting of the '$posts' object if there are multiple lines 
    $response["posts"] = $result; 
    return json_encode($response); 
    } 
    else{ 
    echo 'no active posts for this user ID. '; 
    } 
} 

DBOperations:

public function getUserPosts($queryUserID){ 
    $sql = 'SELECT title, content FROM users JOIN post 
       ON post.userID = users.sno WHERE sno = ?'; 
    $queryStmt = $this -> conn -> prepare($sql); 
    if ($queryStmt -> bindParam(1, $queryUserID, PDO::PARAM_INT)) { 
     echo '<br> userID: '.$queryUserID.' URL parameter bound successfully. </br>'; 
     if($queryStmt -> execute()){ 
      echo '<br> query execution successful. there are rows. </br>'; 
      $resultSet = $queryStmt -> fetchAll(PDO::FETCH_ASSOC); 

      return $resultSet; 
     } 
    } 
} 

这是从服务器我的回应:

url query ID is: 3. <br> userID: 3 URL parameter bound successfully. </br><br> query execution successful. there are rows. </br>{"posts":[{"title":"test title 1","content":"hey this is the content for test title 1"},{"title":"test title 2","content":"hey this is the content for the second post!"}]} 

这是堆栈跟踪和异常:

[Ljava.lang.StackTraceElement; @ efa7528 java.lang.IllegalStateException:预期BEGIN_OBJECT但线是串1列1路$

如果我没有包括所有相关信息,让我知道

+2

虽然你可能会产生JSON,那是你的服务器似乎没有什么根据的错误信息被返回。服务器正在返回一些不以'{'开头的东西,显然。您可能希望通过您的“OkHttpClient”而不是通过Retrofit进行请求,并确切了解服务器为您提供的服务。 – CommonsWare

+0

尝试从getUserPosts中删除两条'echo'行。他们导致响应在json之前获得额外的String消息。 –

+0

你是正确的建议回声线减少。谢谢,现在它给了我“期望一个字符串,但是BEGIN_ARRAY在第1行第58列路径$ .posts”。这是说它期望一个字符串,我的所有帖子对象是?如果是这样的话,当post对象存储在php中的数组中时,如何使它们成为字符串? – user5932019

回答

0

改造期待一个对象,但它正在接收一个字符串。

更换 echo 'url query ID is: '.$queryUserID.'. '; echo $fun -> getPosts($queryUserID);

随着

echo getPosts($queryUserID);

相关问题