You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

问题分析与修复

  1. 请求头未生效:你创建了headers HashMap但没有将其关联到JsonArrayRequest上。Volley的JsonArrayRequest默认构造器不支持直接传入自定义头,需要重写getHeaders()方法来添加认证头。
  2. 构造器参数顺序错误:Movie类的构造器参数顺序是(userId, id, title, body),但你在fetchMovies()中创建实例时传的是(title, userId, id, body),这会导致数据赋值错误。
  3. ViewHolder控件ID重复:MovieHolder中body和id都用了R.id.id_tv,会导致控件引用错误,可能引发闪退。
  4. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 23:10:55