Android Studio中携带Bearer Token访问URL中JSON数组并展示的方法
如何在Volley请求中添加Bearer Token并正常展示数据?
我需要访问需要Bearer Token认证的JSON接口https://api.json-generator.com/templates/z0aMAeTBHKq3/data,Token为2oof0bzpgllll2a8k2fmmh6aaykeu8yptztdzke7。但用当前代码请求时应用空白并闪退,换成无需认证的接口(比如https://jsonplaceholder.typicode.com/posts)就能正常展示。想请教怎么正确把Token加到请求头里,让数据能正常加载展示。
我的代码
MainActivity.java
public class MainActivity extends AppCompatActivity { private RecyclerView recyclerView; private RequestQueue requestQueue; private List<Movie> movieList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); recyclerView = findViewById(R.id.recyclerview); recyclerView.setHasFixedSize(true); recyclerView.setLayoutManager(new LinearLayoutManager(this)); requestQueue = VolleySingleton.getmInstance(this).getRequestQueue(); movieList = new ArrayList<>(); fetchMovies(); } private void fetchMovies() { // 需要认证的接口 String url = "https://api.json-generator.com/templates/z0aMAeTBHKq3/data"; // 无需认证的测试接口 //String url = "https://jsonplaceholder.typicode.com/posts"; JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, url, null, new Response.Listener<JSONArray>() { @Override public void onResponse(JSONArray response) { for (int i = 0 ; i < response.length() ; i ++){ try { JSONObject jsonObject = response.getJSONObject(i); String userId = jsonObject.getString("userId"); String id = jsonObject.getString("id"); String title = jsonObject.getString("title"); String body = jsonObject.getString("body"); Movie movie = new Movie(title , userId , id , body); movieList.add(movie); } catch (JSONException e) { e.printStackTrace(); } MovieAdapter adapter = new MovieAdapter(MainActivity.this , movieList); recyclerView.setAdapter(adapter); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Toast.makeText(MainActivity.this, error.getMessage(), Toast.LENGTH_SHORT).show(); } }); HashMap headers = new HashMap(); String authValue = "Bearer " + "2oof0bzpgllll2a8k2fmmh6aaykeu8yptztdzke7"; headers.put("Authorization", authValue); headers.put("Accept", "application/json; charset=UTF-8"); headers.put("Content-Type", "application/json; charset=UTF-8"); requestQueue.add(jsonArrayRequest); } }
Movie.java
public class Movie { private String userId , id , title, body; public Movie(String userId , String id , String title , String body){ this.title = title; this.userId = userId; this.id = id; this.body = body; } public String getTitle() { return title; } public String getUserId() { return userId; } public String getId() { return id; } public String getBody() { return body; } }
MovieAdapter.java
public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.MovieHolder> { private Context context; private List<Movie> movieList; public MovieAdapter(Context context , List<Movie> movies){ this.context = context; movieList = movies; } @NonNull @Override public MovieHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(context).inflate(R.layout.item , parent , false); return new MovieHolder(view); } @Override public void onBindViewHolder(@NonNull MovieHolder holder, int position) { Movie movie = movieList.get(position); holder.userId.setText(movie.getUserId().toString()); holder.id.setText(movie.getId()); holder.title.setText(movie.getTitle()); holder.body.setText(movie.getBody()); holder.constraintLayout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(context , DetailActivity.class); Bundle bundle = new Bundle(); bundle.putString("userId" , movie.getUserId()); bundle.putString("id" , movie.getId()); bundle.putString("title" , movie.getTitle()); bundle.putString("body" , movie.getBody()); intent.putExtras(bundle); context.startActivity(intent); } }); } @Override public int getItemCount() { return movieList.size(); } public class MovieHolder extends RecyclerView.ViewHolder{ TextView title , userId , id, body; ConstraintLayout constraintLayout; public MovieHolder(@NonNull View itemView) { super(itemView); userId = itemView.findViewById(R.id.userid_tv); title = itemView.findViewById(R.id.title_tv); id = itemView.findViewById(R.id.id_tv); body = itemView.findViewById(R.id.id_tv); constraintLayout = itemView.findViewById(R.id.main_layout); } } }
VolleySingleton.java
public class VolleySingleton { private RequestQueue requestQueue; private static VolleySingleton mInstance; private VolleySingleton(Context context){ requestQueue = Volley.newRequestQueue(context.getApplicationContext()); } public static synchronized VolleySingleton getmInstance(Context context){ if (mInstance == null){ mInstance = new VolleySingleton(context); } return mInstance; } public RequestQueue getRequestQueue(){return requestQueue;} }
问题分析与修复
- 请求头未生效:你创建了headers HashMap但没有将其关联到JsonArrayRequest上。Volley的
JsonArrayRequest默认构造器不支持直接传入自定义头,需要重写getHeaders()方法来添加认证头。 - 构造器参数顺序错误:
Movie类的构造器参数顺序是(userId, id, title, body),但你在fetchMovies()中创建实例时传的是(title, userId, id, body),这会导致数据赋值错误。 - ViewHolder控件ID重复:
MovieHolder中body和id都用了R.id.id_tv,会导致控件引用错误,可能引发闪退。 - Adapter初始化位置错误:你在循环内部每次都创建新的Adapter并设置到RecyclerView,应该在循环结束后统一初始化一次。
修改后的核心代码
修正MainActivity.java的fetchMovies()方法
private void fetchMovies() { String url = "https://api.json-generator.com/templates/z0aMAeTBHKq3/data"; JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, url, null, response -> { for (int i = 0 ; i < response.length() ; i ++){ try { JSONObject jsonObject = response.getJSONObject(i); String userId = jsonObject.getString("userId"); String id = jsonObject.getString("id"); String title = jsonObject.getString("title"); String body = jsonObject.getString("body"); // 修正构造器参数顺序 Movie movie = new Movie(userId, id, title, body); movieList.add(movie); } catch (JSONException e) { e.printStackTrace(); } } // 循环结束后统一设置Adapter MovieAdapter adapter = new MovieAdapter(MainActivity.this, movieList); recyclerView.setAdapter(adapter); }, error -> { // 优化错误提示,避免null指针 String errorMsg = error.getMessage() != null ? error.getMessage() : "请求失败"; Toast.makeText(MainActivity.this, errorMsg, Toast.LENGTH_SHORT).show(); }) { // 重写getHeaders方法添加认证头 @Override public Map<String, String> getHeaders() throws AuthFailureError { HashMap<String, String> headers = new HashMap<>(); String authValue = "Bearer 2oof0bzpgllll2a8k2fmmh6aaykeu8yptztdzke7"; headers.put("Authorization", authValue); headers.put("Accept", "application/json; charset=UTF-8"); headers.put("Content-Type", "application/json; charset=UTF-8"); return headers; } }; requestQueue.add(jsonArrayRequest); }
修正MovieAdapter.java的MovieHolder
public MovieHolder(@NonNull View itemView) { super(itemView); userId = itemView.findViewById(R.id.userid_tv); title = itemView.findViewById(R.id.title_tv); id = itemView.findViewById(R.id.id_tv); // 修正body的控件ID,确保和布局文件中的ID一致 body = itemView.findViewById(R.id.body_tv); constraintLayout = itemView.findViewById(R.id.main_layout); }
内容的提问来源于stack exchange,提问作者Nathan Ocamps
相关产品推荐
相关产品推荐

