Retrofit:onFailure().....预计BEGIN_OBJECT,但是STRING
问题描述:
我试图让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路$
如果我没有包括所有相关信息,让我知道
答
改造期待一个对象,但它正在接收一个字符串。
更换 echo 'url query ID is: '.$queryUserID.'. '; echo $fun -> getPosts($queryUserID);
随着
echo getPosts($queryUserID);
虽然你可能会产生JSON,那是你的服务器似乎没有什么根据的错误信息被返回。服务器正在返回一些不以'{'开头的东西,显然。您可能希望通过您的“OkHttpClient”而不是通过Retrofit进行请求,并确切了解服务器为您提供的服务。 – CommonsWare
尝试从getUserPosts中删除两条'echo'行。他们导致响应在json之前获得额外的String消息。 –
你是正确的建议回声线减少。谢谢,现在它给了我“期望一个字符串,但是BEGIN_ARRAY在第1行第58列路径$ .posts”。这是说它期望一个字符串,我的所有帖子对象是?如果是这样的话,当post对象存储在php中的数组中时,如何使它们成为字符串? – user5932019