Android调用Amadeus航班API遇401错误:Authorization header异常(38191)
开发Android项目时,调用Amadeus Flight Offers API遇到HTTP 401(Unauthorized)错误,错误码38191,提示「Authorization请求头缺失或格式无效」。
构建API基础URL的代码片段
HttpUrl baseHttpUrl = HttpUrl.parse("https://test.api.amadeus.com/v2/shopping/flight-offers"); if (baseHttpUrl != null) { HttpUrl.Builder urlBuilder = baseHttpUrl.newBuilder(); urlBuilder.addQueryParameter("originLocationCode", origin); urlBuilder.addQueryParameter("destinationLocationCode", destination); urlBuilder.addQueryParameter("departureDate", fromDate); urlBuilder.addQueryParameter("returnDate", toDate); // If round-trip search Log.d("SearchActivity", "URL: " + urlBuilder.build()); }
错误详情
errors
0
code 38191
title "Invalid HTTP header"
detail "Missing or invalid format for mandatory Authorization header"
status 401
发起GET请求的方法代码
public String performGetRequest(String endpoint, HttpUrl.Builder urlBuilder) throws IOException { Request request = new Request.Builder() .url(BASE_URL + endpoint) .addHeader("Authorization", "Bearer " + API_KEY) .url(urlBuilder.build()) .build(); try (Response response = client.newCall(request).execute()) { if (response.isSuccessful()) { return response.body().string(); } } return null; }
问题排查与解决指导
核心问题:错误使用API Key作为Bearer令牌
Amadeus API采用OAuth 2.0 Client Credentials认证流程,不能直接将API Key作为Bearer的值,必须先获取有效的访问令牌(Access Token):
- 向
https://test.api.amadeus.com/v1/security/oauth2/token发送POST请求 - 请求参数:
grant_type=client_credentialsclient_id=你的API_KEYclient_secret=你的API_SECRET
- 解析响应中的
access_token字段,这才是需要放到Authorization头里的令牌
次要问题:Request构建中的冗余URL设置
你的Request.Builder先后调用了两次.url(),OkHttp会以最后一次调用为准,虽然不影响头信息,但建议简化代码,直接使用urlBuilder.build()设置URL:
Request request = new Request.Builder() .url(urlBuilder.build()) .addHeader("Authorization", "Bearer " + accessToken) // 这里用获取到的accessToken,不是API_KEY .build();
验证请求头是否正确添加
可以在构建Request后添加日志,确认Authorization头是否存在且格式正确:
Log.d("RequestDebug", "Authorization Header: " + request.header("Authorization"));
完整流程示例
- 先实现获取Access Token的方法:
public String getAmadeusAccessToken() throws IOException { RequestBody formBody = new FormBody.Builder() .add("grant_type", "client_credentials") .add("client_id", YOUR_API_KEY) .add("client_secret", YOUR_API_SECRET) .build(); Request request = new Request.Builder() .url("https://test.api.amadeus.com/v1/security/oauth2/token") .post(formBody) .build(); try (Response response = client.newCall(request).execute()) { if (response.isSuccessful()) { String json = response.body().string(); // 用Gson或其他解析库解析json,获取access_token // 示例(Gson): // TokenResponse tokenResponse = new Gson().fromJson(json, TokenResponse.class); // return tokenResponse.getAccessToken(); return json; // 实际开发中替换为解析后的access_token } } return null; }
- 调用该方法获取令牌后,再发起航班查询请求:
String accessToken = getAmadeusAccessToken(); if (accessToken != null) { String result = performGetRequest(endpoint, urlBuilder); }
内容的提问来源于stack exchange,提问作者shakirul islam
相关产品推荐
相关产品推荐

