okhttp 的常见示例涵盖了 get 和 post 的场景。
但我需要通过 url 获取文件的文件大小。由于我需要通知用户,并且只有在获得他们的批准后才能下载文件。
目前我正在使用此代码
URL url = new URL("http://server.com/file.mp3");
URLConnection urlConnection = url.openConnection();
urlConnection.connect();
int file_size = urlConnection.getContentLength();
Run Code Online (Sandbox Code Playgroud)
在这个 stackoverflow 问题中提到如何在下载文件之前知道文件的大小?
哪个有效,但是当我在我的项目中使用 okhttp 来处理其他 get 请求时,我也希望将它用于这种情况。
我使用 ProgressRequestBody 来显示上传操作的进度。
@Override
public void writeTo(BufferedSink sink) throws IOException {
// see https://github.com/square/okhttp/issues/1587
// JakeWharton commented on 28 Apr 2015 's answer
final BufferedSink progressSink = Okio.buffer(new ForwardingSink(sink) {
long bytesWritten = 0L;
long contentLength = 0L;
@Override
public void write(Buffer source, long byteCount) throws IOException {
if (contentLength == 0) {
contentLength = contentLength();
}
bytesWritten += byteCount;
mListener.onProgressUpdate(bytesWritten,contentLength,bytesWritten == contentLength);
System.out.println("--byte--"+bytesWritten);
super.write(source, byteCount);
}
});
requestBody.writeTo(progressSink);
System.out.println("--byte-- start---");
progressSink.flush();
System.out.println("--byte-- end---");
}
Run Code Online (Sandbox Code Playgroud)
每次执行上传操作时,都会调用此方法两次。起初,我认为问题可能是在 okhttpclient 中添加了用于日志的拦截器,但事实并非如此。谁能帮帮我?谢谢
更多代码:
public …Run Code Online (Sandbox Code Playgroud) 我试图具体弄清楚我使用 OkHttpClient 发送的请求使用了我的应用程序的数据使用量,并且我发现我可以使用TrafficStats来标记线程,然后使用该标记查看它的网络活动。
如果我做类似的事情
TrafficStats.setThreadStatsTag(1234);
okHttpClient.execute(request);
Run Code Online (Sandbox Code Playgroud)
然后它实际上将其标记为“ok”(ish),但是当我使用异步方法(okHttpClient.enqueue(request))时,它没有(这很明显,尽管我希望他们对此有支持)。
所以我尝试了几件事:
有任何想法吗?
我正在通过HttpLogInterceptor实现打印日志。但发生了错误。
10-04 05:22:55.753 21294-21851/com.tc.retorfit_okhttp_cache_technique E/AndroidRuntime: FATAL EXCEPTION: OkHttp Dispatcher
Process: com.tc.retorfit_okhttp_cache_technique, PID: 21294
java.lang.NoSuchMethodError: No virtual method log(Ljava/lang/String;)V in class Lokhttp3/internal/Platform; or its super classes (declaration of 'okhttp3.internal.Platform' appears in /data/data/com.tc.retorfit_okhttp_cache_technique/files/instant-run/dex/slice-okhttp-3.3.0_b69c4d16ac6ddca06e0d47d36f15c48706942fa9-classes.dex)
at okhttp3.logging.HttpLoggingInterceptor$Logger$1.log(HttpLoggingInterceptor.java:109)
at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:157)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:170)
at okhttp3.RealCall.access$100(RealCall.java:33)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:120)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
at okhttp3.logging.HttpLoggingInterceptor$Logger$1.log(HttpLoggingInterceptor.java:109)
Run Code Online (Sandbox Code Playgroud)
错误在以下代码中:
public interface Logger {
void log(String message);
/** A {@link Logger} defaults output appropriate for the current platform. */
Logger DEFAULT = …Run Code Online (Sandbox Code Playgroud) 我在 Android 上使用 Retrofit2 和 OkHttp 进行 HTTP 请求。这里我正在做一个带有文档上传的 POST 请求。我遇到了以下错误:
D/OkHttp: <-- 500 Server Error http://api.drivewealth.io/v1/documents (4289ms)
D/OkHttp: Date: Tue, 11 Apr 2017 03:29:48 GMT
D/OkHttp: Cache-Control: must-revalidate,no-cache,no-store
D/OkHttp: Content-Type: text/html; charset=ISO-8859-1
D/OkHttp: Server: Jetty(9.2.17.v20160517)
D/OkHttp: Content-Length: 9323
D/OkHttp: Connection: keep-alive
D/OkHttp: <html>
D/OkHttp: <head>
D/OkHttp: <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
D/OkHttp: <title>Error 500 Server Error</title>
D/OkHttp: </head>
D/OkHttp: <body><h2>HTTP ERROR 500</h2>
D/OkHttp: <p>Problem accessing /v1/documents. Reason:
D/OkHttp: <pre> Server Error</pre></p><h3>Caused by:</h3><pre>org.apache.cxf.interceptor.Fault: Couldn't determine the boundary from the message!
D/OkHttp: …Run Code Online (Sandbox Code Playgroud) 是否有办法强制 OkHttp 通过蜂窝网络发出请求?
我的应用程序有某些请求必须通过蜂窝网络(3G、LTE、4G,而不是 Wifi)发送。我将 Retrofit 和 OkHttp 用于所有其他网络请求,因此我也想将它用于这些请求。看起来ConnectivityManger.registerDefaultNetworkCallback()可以提供帮助,但仅支持 API 21+。我想要一个适用于 API 19+ 的解决方案。
我已经完成了与此相关的所有问题,但是,我还没有找到适合我的解决方案。
我正在使用retrofit 2.8.1和OkHttp 4.5.0。
我的服务界面如下所示
public interface MlApiService
{
@POST
@Multipart
Call<List<PreprocessedDocument>> postDocument( @Url String apiUrl, @Part MultipartBody.Part document,
@Part ( "document_id") RequestBody documentId );
}
Run Code Online (Sandbox Code Playgroud)
我构建了客户端,如下所示,requestTimeoutInSeconds设置为 90 秒。
public void init()
{
GsonBuilder gson = new GsonBuilder();
gson.registerTypeAdapter( new TypeToken<List<PreprocessedDocument>>() {}.getType(), new CustomResponseDeserializer() );
HttpLoggingInterceptor logInterceptor = new HttpLoggingInterceptor();
logInterceptor.setLevel( HttpLoggingInterceptor.Level.HEADERS );
OkHttpClient client = new OkHttpClient.Builder().retryOnConnectionFailure( true ).addInterceptor( logInterceptor )
.readTimeout( requestTimeoutInSeconds, TimeUnit.SECONDS ).build();
//Dummy Base URL must be provided. otherwise client …Run Code Online (Sandbox Code Playgroud) 我正在开发一个使用 Retrofit 进行网络操作的应用程序。就目前而言,一切都可以很好地GsonConverterFactory处理序列化。这是我如何设置Retrofit
Retrofit.Builder()
.baseUrl("<base url>")
.client(client)
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
Run Code Online (Sandbox Code Playgroud)
现在我需要连接到以text/plain; charset=utf-8格式返回内容的旧服务。这是改造界面
@GET("https://<domain>/<endpoint>?Type=Query")
suspend fun callStatus(@Query("userId") id: Int): Response<String>
Run Code Online (Sandbox Code Playgroud)
这将为有效用户返回呼叫状态。例如,如果用户有效并且有状态,它会以纯文本形式返回“Active”。如果没有有效用户,则返回错误代码#1005
我可以像这样添加自定义转换器工厂(在网上找到)
final class StringConverterFactory implements Converter.Factory {
private StringConverterFactory() {}
public static StringConverterFactory create() {
return new StringConverterFactory();
}
@Override
public Converter<String> get(Type type) {
Class<?> cls = (Class<?>) type;
if (String.class.isAssignableFrom(cls)) {
return new StringConverter();
}
return null;
}
private static class StringConverter implements Converter<String> {
private static final MediaType PLAIN_TEXT = MediaType.parse("text/plain; charset=UTF-8");
@Override …Run Code Online (Sandbox Code Playgroud) 当我使用 mockhttpserver 测试 http 请求时出现上述错误,以下代码是我创建服务的方式。
fun <T> getService(clazz: Class<T>): T {
val client = OkHttpClient.Builder().addInterceptor(HeaderInterceptor()).addInterceptor(HttpLoggingInterceptor().apply { level = if (BuildConfig.DEBUG) HttpLoggingInterceptor.Level.BODY else HttpLoggingInterceptor.Level.NONE })
.build()
return Retrofit.Builder()
.baseUrl(mockWebServer.url(""))
.client(client)
.addConverterFactory(GsonConverterFactory.create(GSON))
.build()
.create(clazz)
}
Run Code Online (Sandbox Code Playgroud)
这是我的测试代码。
@UninstallModules(HomePageDataModule::class)
@HiltAndroidTest
class TestHomePageViewModel {
private lateinit var viewModel: HomePageViewModel
@get:Rule
var hiltRule = HiltAndroidRule(this)
@Inject
lateinit var cpd: CompositionDao
@Inject
lateinit var csd: CompositionsDao
@Inject
lateinit var hpds: HomePageDataSource
@Inject
lateinit var ss :HomePageService
@Before
fun init() {
hiltRule.inject()
viewModel = HomePageViewModel(HomeCompositionsRepository(cpd, csd, hpds, Util.GSON)) …Run Code Online (Sandbox Code Playgroud) Maven 依赖
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>mockwebserver</artifactId>
<version>4.9.0</version>
<scope>test</scope>
</dependency>
Run Code Online (Sandbox Code Playgroud)
我写的测试
@SpringJUnitConfig(classes = {GithubApiService.class, WebClientConfiguration.class})
@EnableAutoConfiguration
public class GithubApiServiceTest {
@Test
public void testGithubResponseJsonToMapConversion(
@Autowired GithubApiService service,
@Value("classpath:github/commit-payload.json") Resource commitPayloadFile) throws IOException {
final String COMMITS_URL = "/repos/Codertocat/Hello-World/commits/sha";
//Stub response from Github Server
String responseJson = new ObjectMapper().writeValueAsString(
new String(Files.readAllBytes(Paths.get(commitPayloadFile.getFile().getAbsolutePath()))));
MockWebServer server = new MockWebServer();
server.enqueue(new MockResponse()
.addHeader("Content-Type", "application/json; charset=utf-8")
.setBody(responseJson)
.setResponseCode(OK.value()));
server.start();
// Get mock server's URL
HttpUrl mockGithubUrl = server.url(COMMITS_URL);
//Call API Service
Map<String, Object> result = service.getCommitDetails(mockGithubUrl.toString()).block();
//Expect return …Run Code Online (Sandbox Code Playgroud) okhttp ×10
android ×7
retrofit2 ×5
java ×3
retrofit ×3
gunicorn ×1
kotlin ×1
multipart ×1
networking ×1
spring-boot ×1