我正在使用 okhttp 和 Retrofit 来调用 REST 服务。从该服务返回的数据存储在我的 Android 应用程序中的 sqlite 数据库中。
每当我调用 REST api 时,如果数据没有更改(由 ETag 或 Last-Modified 标头确定),我希望 Retrofit 回调不执行任何操作(数据库中的数据没问题)。否则,我想从 REST 服务下载更新的 JSON 并更新数据库(通过回调的 onSuccess 方法)。
关于缓存响应的所有设置磁盘缓存的 okhttp 示例,我只需要缓存/存储每个请求的 Etag/上次修改时间(而不是整个响应)。
我应该通过传递给 okhttp 的自定义缓存实现来执行此操作,还是应该与 okhttp 或 Retrofit 一起使用更好的接口?
一旦我完成了实现设置,我是否只需要在 onFailure 回调中处理304“错误”而不执行任何操作?
我一直在寻找关于这个主题的一段时间。我正在尝试使用OkHttp. 但是,我收到此错误:
okhttp3.internal.http2.StreamResetException: stream was reset:PROTOCOL_ERROR
val client = OkHttpClient()
val response = client.newCall(
Request.Builder()
.addHeader("Authorization:", "Bearer $firebaseToken")
.url("https://someURL/"+ podcastId.toString())
.build())
.execute()
Run Code Online (Sandbox Code Playgroud)
我不确定这是否与标题URL或我的Authorization标题有关?任何帮助将不胜感激,提前致谢。
这是我第一次使用OkHttp,想先学习一些基本的代码。
所以这是代码,取自here:
package com.anta40.app.okconnectiontest;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class MainClass {
public static void main(String args[]) {
OkHttpClient okcl = new OkHttpClient();
Request request = new Request.Builder()
.url("http://www.vogella.com/index.html")
.build();
okcl.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, final Response response) throws IOException {
if (!response.isSuccessful()) {
throw new IOException("Unexpected code " + response);
}
else {
System.out.println("okay.....");
}
} …Run Code Online (Sandbox Code Playgroud) 我对这个特定网站有问题:https : //tastedive.com/read/api
如果我使用 HttpURLConnection 执行 HTTP 请求,我会得到一个正常的 HTML 响应(在 Android 上,此代码需要位于一个单独的线程中,并且还进行了所有必要的尝试和捕获):
StringBuilder result = new StringBuilder();
URL url = new URL("https://tastedive.com/read/api");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = rd.readLine()) != null) {
result.append(line);
}
rd.close();
System.out.println(result.toString()); // shows normal HTML response
Run Code Online (Sandbox Code Playgroud)
但是如果我用 OkHttp 来做,用这个代码......
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://tastedive.com/read/api")
.build();
client.newCall(request).enqueue(new okhttp3.Callback() {
@Override
public void onFailure(okhttp3.Call call, IOException e) {
Log.d("MY", …Run Code Online (Sandbox Code Playgroud) 根据一些参考资料,例如 Android 在内部使用 OkHttp 吗? Android 在 HttpUrlConnection 下内部正在使用(或至少正在使用)okHttp。仍然在最近的一些讨论中(例如,为什么 Android 的 HttpUrlConnection 不支持 HTTP/2?)建议使用来自 GitHub 的 okHttp 而不是 Android http API。所以我很困惑。有没有人有明确的答案?
当我的应用程序的访问令牌过期时,我使用刷新令牌通过 Authenticator 类获取新的访问令牌。
我的代码如下:
if (response.code() == 401) {
Log.d("refresh", "Access token expired")
val webservice: Webservice = RetrofitClient.makeRetrofitService().create(Webservice::class.java)
var refreshToken = PreferenceData.getUserLoggedInRefreshToken(App.GetContext()!!)
var map = generateRequestBody(mapOf("refreshToken" to refreshToken!!))
var refreshResponse = webservice.refreshToken(map).execute()
if (refreshResponse != null && refreshResponse.code() == 200) {
Log.d("refresh", "New access token received")
var newToken = (refreshResponse.body() as UserLogin).token
var refreshToken = (refreshResponse.body() as UserLogin).refreshToken
PreferenceData.setUserLoggedInAccessToken(App.GetContext()!!, newToken)
PreferenceData.setUserLoggedInRefreshToken(App.GetContext()!!, refreshToken)
return response.request().newBuilder()
.header("Authorization", "Bearer $newToken")
.build();
}
}
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好。我现在想做的是当我的刷新令牌过期时,我想将用户重定向到应用程序的登录屏幕。但我的问题是,当我打电话
var refreshResponse = webservice.refreshToken(map).execute()
服务器也返回 401。所以我的问题是我不知道我收到的 401 是由于访问令牌已过期还是刷新令牌已过期。处理这个问题最合适的方法是什么?
谢谢!
我请求链接以获取 JSON 但 response.body().string() 值总是有错误。另一种方式,我将 response.body().string() 拆分为 response.body() 和 string 但 Android studio 没有找到 ResponseBody。2 方法不起作用。请帮忙!
String doGetRequest(String url) throws IOException {
Request request = new Request.Builder()
.url(url)
.build();
try (Response response = client.newCall(request).execute()) {
System.out.println(response.body().string());
//ResponseBody responseBody = response.body();
//String content = responseBody.string();
//System.out.println(content);
return response.body().string();
}
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试运行使用 okhttp3 进行 Rest api 调用的示例代码。
MoshiJsonConvertor.kt:
import com.squareup.moshi.JsonClass
import com.squareup.moshi.Moshi
import okhttp3.OkHttpClient
import okhttp3.Request
import java.io.IOException
class MoshiJsonConvertor {
private val client = OkHttpClient()
private val moshi = Moshi.Builder().build()
private val gistJsonAdapter = moshi.adapter(Gist::class.java)
fun run() {
val request = Request.Builder()
.url("https://api.github.com/gists/c2a7c39532239ff261be")
.build()
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) throw IOException("Unexpected code $response")
val gist = gistJsonAdapter.fromJson(response.body!!.source())
for ((key, value) in gist!!.files!!) {
println(key)
println(value.content)
}
}
}
@JsonClass(generateAdapter = true)
data class Gist(var files: Map<String, GistFile>?)
@JsonClass(generateAdapter = …Run Code Online (Sandbox Code Playgroud) 我最近开始更新 okhttp3 到 4.x
在这样做时,我收到以下构建时间错误:
Using 'url(): HttpUrl' is an error. moved to val
当我尝试从通过调用获得的请求对象中获取 url 时,问题发生了:
例如
call.enque(callback : Callback){
override fun onFailure(call : Call, t:Throwable) {
val url = call.request().url().toString
}
}
Run Code Online (Sandbox Code Playgroud)
我进一步抬头,里面的Url物体Request现在是 val aka final。
此外,他们的升级指南https://square.github.io/okhttp/upgrading_to_okhttp_4/上没有说明
如果您对获取 Url 的其他方式有任何建议,我将不胜感激。
我想从okhttp3.RequestBody. 任何人都可以帮忙吗?