我正在使用OkHttp来获取某些网站的内容.
但是,我无法从响应中获取Http-Status Code.
我的Java代码:
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://www.google.at")
.build();
Response httpResponse = client.newCall(request).execute();
String html = httpResponse.body().string();
Run Code Online (Sandbox Code Playgroud)
这个方法:
httpResponse.toString();
Run Code Online (Sandbox Code Playgroud)
返回以下内容:
Response{protocol=http/1.1, code=200, message=OK, url=https://www.google.at}
Run Code Online (Sandbox Code Playgroud)
有没有办法将statusCode作为一个整数,或者我是否需要一个正则表达式来过滤掉这个toString()方法?
这是我运行最近继承的Android应用程序时获得的堆栈跟踪.我们没有使用OkHttp作为显式依赖,并且com.android.okhttp跟踪让我觉得AOSP现在在内部使用OkHttp?
java.lang.Throwable: Explicit termination method 'close' not called
E at dalvik.system.CloseGuard.open(CloseGuard.java:184)
E at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:278)
E at com.android.okhttp.Connection.upgradeToTls(Connection.java:146)
E at com.android.okhttp.Connection.connect(Connection.java:107)
E at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:294)
E at com.android.okhttp.internal.http.HttpEngine.sendSocketRequest(HttpEngine.java:255)
E at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:206)
E at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:345)
E at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:296)
E at com.android.okhttp.internal.http.HttpURLConnectionImpl.getHeaderField(HttpURLConnectionImpl.java:143)
E at java.net.URLConnection.getHeaderFieldInt(URLConnection.java:544)
E at java.net.URLConnection.getContentLength(URLConnection.java:316)
E at com.android.okhttp.internal.http.HttpsURLConnectionImpl.getContentLength(HttpsURLConnectionImpl.java:182)
Run Code Online (Sandbox Code Playgroud) 我想在Android中使用OkHttp库进行网络连接.我从他们网站上写的简单帖子示例开始:
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
String post(String url, String json) throws IOException {
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
}
Run Code Online (Sandbox Code Playgroud)
通过这个电话:
String response = post("http://www.roundsapp.com/post", json);
Run Code Online (Sandbox Code Playgroud)
此调用以NetworkOnMainThreadException结束.
我可以使用AsyncTask包装调用,但据我从示例中了解,OkHttp库应该已经处理过了.我做错了什么?
我希望将REST服务作为gzip编码的JSON使用.它提供了Content-Encoding: gzip,但我的OkHttp不会将其编码为可读文本,因此JSON转换器会抛出异常.
---> HTTP GET https://rapla.dhbw-karlsruhe.de/rapla/events?resources=%5B%27rc85dbd6-7d98-4eb7-a7f6-b867213c73d8%27%5D&start=2015-09-01&end=2015-12-31
Accept-Encoding: gzip, deflate
Accept: application/json
Authorization: *not posted*
Content-Type: application/json;charset=utf-8
---> END HTTP (no body)
<--- HTTP 200 https://rapla.dhbw-karlsruhe.de/rapla/events?resources=%5B%27rc85dbd6-7d98-4eb7-a7f6-b867213c73d8%27%5D&start=2015-09-01&end=2015-12-31 (13ms)
Date: Tue, 24 Nov 2015 09:09:10 GMT
Server: Jetty(9.2.2.v20140723)
Expires: Tue, 01 Jan 1980 00:00:00 GMT
Pragma: no-cache
Cache-Control: no-cache, must-revalidate
Content-Encoding: gzip
Content-Type: application/json; charset=utf-8
Content-Disposition: attachment
Content-Length: 9684
Via: 1.1 rapla.dhbw-karlsruhe.de
Keep-Alive: timeout=5, max=99
Connection: Keep-Alive
OkHttp-Selected-Protocol: http/1.1
OkHttp-Sent-Millis: 1448356149978
OkHttp-Received-Millis: 1448356149991
????WK?{??J?`k?_??Z????E?p?>3m?WMa?????p?0??<??
... skipped rest of the body
E??>???S???n …Run Code Online (Sandbox Code Playgroud) 我在Android应用程序中使用Retrofit 2(2.0.0-beta3)和OkHttp客户端,到目前为止一切都很顺利.但目前我正面临着OkHttp Interceptor的问题.我正在与之通信的服务器正在请求主体中访问令牌,因此当我需要添加更新的身份验证令牌时,当我拦截添加身份验证令牌的身份验证或身份验证器的身份验证方法时,我需要为此目的修改请求体.但看起来我只能在标题中添加数据,但不能在正在进行的请求中添加数据.我到目前为止编写的代码如下:
client.interceptors().add(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (UserPreferences.ACCESS_TOKEN != null) {
// need to add this access token in request body as encoded form field instead of header
request = request.newBuilder()
.header("access_token", UserPreferences.ACCESS_TOKEN))
.method(request.method(), request.body())
.build();
}
Response response = chain.proceed(request);
return response;
}
});
Run Code Online (Sandbox Code Playgroud)
任何人都可以指出正确的方向,如何修改请求体以添加我的访问令牌(第一次或在令牌刷新后更新)?任何指向正确方向的指针都将受到赞赏.
我有一个Retrofit网络调用,id喜欢每5秒运行一次.我目前的代码:
Handler h = new Handler();
int delay = 5000; //milliseconds
h.postDelayed(new Runnable() {
public void run() {
call.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(Response<ApiResponse> response) {
Log.d("api", "response: " + response.body().getPosition().getLatitude().toString());
}
@Override
public void onFailure(Throwable t) {
}
});
h.postDelayed(this, delay);
}
}, delay);
Run Code Online (Sandbox Code Playgroud)
这运行一次,但随后抛出以下内容:
java.lang.IllegalStateException:已经执行.at retrofit2.OkHttpCall.enqueue(OkHttpCall.java:52)at retrofit2.ExecutorCallAdapterFactory $ ExecutorCallbackCall.enqueue(ExecutorCallAdapterFactory.java:57)at orbyt.project.MyFragment $ 1.run(MyFragment.java:93)
这是什么问题?
作为奖励:什么是更好的方法来处理这个?我会在每次更新时更新地图.我正在考虑尝试使用Rx,但不确定这是否是一个合适的用例,或者如何实现它.
我正在使用Retrofit将图像上传到我的服务器.在这里,我需要为单个密钥上传多个图像.我已经尝试使用Postman Web客户端,它运行良好.这是一个截图.
以下是请求的键值对.
SurveyImage:[file1,file2,file3];
PropertyImage:文件
DRA:jsonBody
我试图用Retrofit做同样的事情.但图像没有上传到服务器.这是我的代码.
WebServicesAPI.java
public interface WebServicesAPI {
@Multipart
@POST(WebServices.UPLOAD_SURVEY)
Call<UploadSurveyResponseModel> uploadSurvey(@Part MultipartBody.Part surveyImage, @Part MultipartBody.Part propertyImage, @Part("DRA") RequestBody dra);
}
Run Code Online (Sandbox Code Playgroud)
这是上传文件的方法.
private void requestUploadSurvey() {
File propertyImageFile = new File(surveyModel.getPropertyImagePath());
RequestBody propertyImage = RequestBody.create(MediaType.parse("image/*"), propertyImageFile);
MultipartBody.Part propertyImagePart = MultipartBody.Part.createFormData("PropertyImage", propertyImageFile.getName(), propertyImage);
JSONObject requestBody = getRequestBody();
RequestBody draBody = null;
try {
draBody = RequestBody.create(MediaType.parse("text/plain"), requestBody.toString(1));
Log.d(TAG, "requestUploadSurvey: RequestBody : " + requestBody.toString(1));
} catch (JSONException e) {
e.printStackTrace();
}
MultipartBody.Builder builder = new MultipartBody.Builder();
builder.setType(MultipartBody.FORM); …Run Code Online (Sandbox Code Playgroud) ProGuard不会与okhttp玩得很好,我会继续收到以下警告:
Warning:com.squareup.okhttp.internal.huc.HttpsURLConnectionImpl: can't find referenced method 'long getContentLengthLong()' in program class com.squareup.okhttp.internal.huc.HttpURLConnectionImpl
Warning:com.squareup.okhttp.internal.huc.HttpsURLConnectionImpl: can't find referenced method 'long getHeaderFieldLong(java.lang.String,long)' in program class com.squareup.okhttp.internal.huc.HttpURLConnectionImpl
Warning:com.squareup.okhttp.internal.huc.JavaApiConverter$CacheHttpsURLConnection: can't find referenced method 'long getContentLengthLong()' in program class com.squareup.okhttp.internal.huc.JavaApiConverter$CacheHttpURLConnection
Warning:com.squareup.okhttp.internal.huc.JavaApiConverter$CacheHttpsURLConnection: can't find referenced method 'long getHeaderFieldLong(java.lang.String,long)' in program class com.squareup.okhttp.internal.huc.JavaApiConverter$CacheHttpURLConnection
Warning:there were 4 unresolved references to program class members.
Your input classes appear to be inconsistent.
You may need to recompile the code.
(http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedprogramclassmember)
Run Code Online (Sandbox Code Playgroud)
这些是我的okhttp和改造的proguard设置:
-dontwarn rx.**
-dontwarn okio.**
-dontwarn com.squareup.okhttp.*
-dontwarn retrofit.appengine.UrlFetchClient
-keep class …Run Code Online (Sandbox Code Playgroud) 我想在另一个线程(如IO线程)中使用okhttp请求一个url并进入ResponseAndroid主线程,但我不知道如何创建一个Observable.
如何LoginActivity从拦截器(非活动类)开始?我已经尝试过Interceptor下面的代码()但不适合我.
拦截器
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request newRequest = chain.request().newBuilder()
.addHeader("Authorization", "Bearer " + auth_token_string)
.build();
Response response = chain.proceed(newRequest);
Log.d("MyApp", "Code : "+response.code());
if (response.code() == 401){
Intent intent = new Intent(SplashActivity.getContextOfApplication(), LoginActivity.class);
startActivity(intent);
finish(); //Not working
return response;
}
return chain.proceed(newRequest);
}
}).build();
Run Code Online (Sandbox Code Playgroud)
这是我正在使用的当前解决方案,有没有比这更好的解决方案?该解决方案必须在每次api呼叫时保持重复.
主要活动
call.enqueue(new Callback<Token>() {
@Override
public void onResponse(Call<Token> call, Response<Token> response) {
if(response.isSuccessful())
{
//success
}
else
{
Intent …Run Code Online (Sandbox Code Playgroud)