我在Retrofit API中找不到用于记录完整请求/响应主体的相关方法.我期待在Profiler中提供一些帮助(但它只提供有关响应的元数据).我尝试在Builder中设置日志级别,但这对我没有帮助:
RestAdapter adapter = (new RestAdapter.Builder()).
setEndpoint(baseUrl).
setRequestInterceptor(interceptor).
setProfiler(profiler).
setClient(client).
setExecutors(MyApplication.getWebServiceThreadPool()).
setLogLevel(LogLevel.FULL).
setLog(new RestAdapter.Log() {
@Override
public void log(String msg) {
Log.i(TAG, msg);
}
}).
build();
Run Code Online (Sandbox Code Playgroud)
编辑:此代码现在正在运行.我不知道它为什么不提前工作.可能是因为我正在使用一些旧版本的改造.
我现在从Volley转到Retrofit 2.0版本.
如何打印完整的json响应代码?
包括:
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
Run Code Online (Sandbox Code Playgroud)
RestClient:
OkHttpClient client = new OkHttpClient();
client.interceptors().add(new Interceptor() {
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
return response;
}
});
Gson gson = new GsonBuilder()
.setDateFormat("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'SSS'Z'")
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ROOT)
.addConverterFactory(GsonConverterFactory.create(gson))
.client(client)
.build();
REST_CLIENT = retrofit.create(APIService.class);
Run Code Online (Sandbox Code Playgroud)
APIService:
@GET("my/json")
Call<Model> getFeed();
Run Code Online (Sandbox Code Playgroud)
在活动中 - 调用API:
Call<Model> call = RestClient.get().getFeed();
call.enqueue(new Callback<Model>() {
@Override
public void onResponse(Response<Model> response, Retrofit retrofit) {
Log.w("2.0 getFeed …Run Code Online (Sandbox Code Playgroud) 我正在使用Charles(http://www.charlesproxy.com)来调试我的HTTP请求,现在我遇到了一个问题,我收到了json响应,我需要编辑它以查看我的应用程序的行为.
我在看Rewrite选项,但无法弄清楚如何更改它.理想的是从磁盘加载整个响应.
任何想法如何实现这一目标?谢谢.
我正在使用Retrofit 2制作一个Android应用程序.我的REST Api都是用Liferay编写的.现在在Liferay中,我所看到的是,访问我们需要首先进行身份验证的Web服务.所以我已经这样认证了
http://test:q1w2e3r4@192.168.0.110:8080/liferay-portlet/api/secure/jsonws/
Run Code Online (Sandbox Code Playgroud)
Liferay有自己的用户身份验证方法,我们已经覆盖了.我检查了Postman的Web服务调用工作正常.
URL:http://test:q1w2e3r4@192.168.0.110:8080/liferay-portlet/api/secure/jsonws/customuserauthentication/authenticate-by-user-name
Run Code Online (Sandbox Code Playgroud)
形式编码的值
companyId:10154
screenName:xyz
password:xyz
active:true
Run Code Online (Sandbox Code Playgroud)
如果我把它放在邮递员中,它会正确地获取json响应.
现在,当我从我的Android代码中调用相同的内容时,我得到一个响应"未经授权".
我的改造服务
public interface LoginApi {
@FormUrlEncoded
@POST("/liferay-portlet/api/secure/jsonws/customuserauthentication/authenticate-by-user-name")
Call<User> login(@Field("companyId")long companyId,@Field("screenName")String screenName,@Field("password")String password,@Field("active")boolean active);
}
Run Code Online (Sandbox Code Playgroud)
我的RestApiManager类(此类用于调用服务接口并创建改造构建器)
public class RestApiManager {
private LoginApi loginApi;
public LoginApi login() {
if (loginApi==null) {
GsonBuilder gson=new GsonBuilder();
gson.registerTypeAdapter(String.class, new StringDeserializer());
Retrofit retrofit=new Retrofit.Builder()
.baseUrl("http://test:q1w2e3r4@192.168.0.110:8080")
.addConverterFactory(GsonConverterFactory.create())
.build();
loginApi=retrofit.create(LoginApi.class);
}
return loginApi;
}
Run Code Online (Sandbox Code Playgroud)
调用RestApiManager
Call<User> callUser=restApiManager.login().login(loginData.getCompanyId(),loginData.getScreenName(),loginData.getPassword(),loginData.isActive());
callUser.enqueue(new Callback<User>() {
@Override
public void onResponse(Response<User> response, Retrofit retrofit) {
Log.d("Login","Login Response:"+response.body());
}
@Override
public …Run Code Online (Sandbox Code Playgroud) 我的Retrofit配置出了什么问题?我在使用OkHttpClient添加基本身份验证时出现此错误,但是当我使用没有Interceptor的默认客户端时,它正在运行.或者我的Gradle Dependencies有什么问题吗?
E/AndroidRuntime? FATAL EXCEPTION: main
java.lang.IllegalArgumentException
: HTTP method annotation is required (e.g., @GET, @POST, etc.).
for method APIService.getRegAccrDetails
at retrofit.Utils.methodError(Utils.java:177)
at retrofit.Utils.methodError(Utils.java:167)
at retrofit.RequestFactoryParser.parseMethodAnnotations(RequestFactoryParser.java:135)
at retrofit.RequestFactoryParser.parse(RequestFactoryParser.java:59)
at retrofit.MethodHandler.create(MethodHandler.java:30)
at retrofit.Retrofit.loadMethodHandler(Retrofit.java:151)
at retrofit.Retrofit$1.invoke(Retrofit.java:132)
at $Proxy0.getRegAccrDetails(Native Method)
at alvin.test.myapplication.MainActivity.liferayAccess(MainActivity.java:136)
at alvin.test.myapplication.MainActivity.access$000(MainActivity.java:28)
at alvin.test.myapplication.MainActivity$1.onClick(MainActivity.java:49)
at android.view.View.performClick(View.java:3511)
at android.view.View$PerformClick.run(View.java:14105)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4424)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
Run Code Online (Sandbox Code Playgroud)
这是我要调用的API服务
@GET("Triu-services-portlet.regaccrdetails/get-all-reg-accr-details-by-num-branch-code/num/{num}/branch-code/{branch-code}")
public Observable<List<RegAccrDetails>> getRegAccrDetails(@Path("num") String num, @Path("branch-code")String branchCode);
Run Code Online (Sandbox Code Playgroud)
我的OkHttpClient拦截器
private static OkHttpClient …Run Code Online (Sandbox Code Playgroud) 我正在retrofit调用一个Web服务并且改造失败了,来自'Throwable`的消息给了我
java.lang.IllegalStateException:预期BEGIN_OBJECT但是在第1行第1行STRING STRING
我假设这是因为.Net Web服务抛出错误而不返回JSON.但为了证明这一点,我需要能够看到原始响应onFailure.无论如何我能做到吗?
这是我正在使用的代码
public void userLoginRequestEvent(final AuthenticateUserEvent event) {
Call call = sApi.login(event.getUsername(), event.getPassword(), OS_TYPE, DeviceInfoUtils.getDeviceName());
call.enqueue(new Callback<LoggedInUser>() {
@Override
public void onResponse(Response<LoggedInUser> response, Retrofit retrofit) {
// response.isSuccess() is true if the response code is 2xx
if (response.isSuccess()) {
LoggedInUser user = response.body();
AppBus.getInstance()
.post(new UserIsAuthenticatedEvent(user, event.getUsername(),
event.getPassword()));
} else {
int statusCode = response.code();
// handle request errors yourself
}
}
@Override
public void onFailure(Throwable t) {
// handle execution failures …Run Code Online (Sandbox Code Playgroud) 我在android上使用RetroFit以便将图像发送到REST服务器(使用Python和Flask开发)。该应用程序将第一张图像发送到存储该图像的服务器,并将该图像的ID返回给客户端。然后,客户端拍摄另一张照片并将其发送到服务器,这次是在端点URL中使用先前的图像ID。然后,服务器应计算从图像A到图像B的旋转并返回结果。客户端发送完第二张图像后,它应重复轮询端点以获取结果,直到服务器端计算完成。
第一个图像正确发送,服务器将其存储。客户端然后正确地从服务器接收响应。当客户端发送第二个图像时,会出现问题。服务器正确接收了POST,但是客户端似乎从未收到响应。第三条消息(轮询结果的GET请求)也是如此,服务器已接收到该消息,但客户端从未看到响应。
我的REST服务器的代码在这里
class Image(Resource):
def post(self):
file = request.files['uploaded_file']
centerX = request.form['center_x']
centerY = request.form['center_y']
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], str(id(True)) + ".jpg"))
result = {'id' : id(), 'error' : True, 'result' : 5.5}
return jsonify(result)
else:
return {'id' : -1, 'error' : False}
class Find_Transform(Resource):
def post(self, first_id):
result = {'id' : 1, 'error' : True, 'result' : 1.2}
return jsonify(result)
class Find_Transform_Result(Resource):
def get(self, first_id, second_id):
print("Hello")
result = {'id' : 0, 'error' : …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用Retrofit(2.0.0-beta3),但是当使用Authenticator添加令牌时,我似乎无法从同步调用中获取数据.我们在后端的日志记录只显示了很多登录尝试,但我无法从正文中获取实际添加到标题的数据.
public static class TokenAuthenticator implements Authenticator {
@Override
public Request authenticate(Route route, Response response) throws IOException {
// Refresh your access_token using a synchronous api request
UserService userService = createService(UserService.class);
Call<Session> call = userService.emailLogin(new Credentials("handle", "pass"));
// This call is made correctly, as it shows up on the back-end.
Session body = call.execute().body();
// This line is never hit.
Logger.d("Session token: " + body.token);
// Add new header to rejected request and retry it
return response.request().newBuilder()
.header("Auth-Token", body.token)
.build(); …Run Code Online (Sandbox Code Playgroud) Retrofit的先前版本使用RestAdapter并提供了启用日志的功能。为什么在Retrofit 2.0中删除了该功能?
要启用日志,我必须这样做。
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
/** Handles Log */
retrofit.client().interceptors().add(new LoggingInterceptor());
class LoggingInterceptor implements Interceptor {
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request();
long t1 = System.nanoTime();
Logger.d(String.format("Sending request %s on %s%n%s",
request.url(), chain.connection(), request.headers()));
Response response = chain.proceed(request);
long t2 = System.nanoTime();
Logger.d(String.format("Received response for %s in %.1fms%n%s",
response.request().url(), (t2 - t1) / 1e6d, response.headers()));
// Logger.d(""+new String(response.body().bytes()));
return response;
}
Run Code Online (Sandbox Code Playgroud)
这是唯一的解决方案?以前的规定非常方便...
我以前使用过gson自动转换为pojo的。
但现在我正在尝试使用改造将api结果转换为对象。
只要json已命名对象数组,就没有问题:
{
items:[
{"name":"foo"},
{"name":"bar"}
]
}
Run Code Online (Sandbox Code Playgroud)
public class AnItem {
String name;
}
public class MyItems {
List<AnItem> items;
}
public interface MyApi {
@GET("/itemlist")
Call<MyItems> loadItems();
}
public boolean onOptionsItemSelected(MenuItem item) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://someurl.com/api")
.addConverterFactory(GsonConverterFactory.create())
.build();
MyApi myApi = retrofit.create(MyApi.class);
Call<MyApi> call = myApi.loadItems();
call.enqueue(this);
return true;
}
@Override
public void onResponse(Response<MyItems> response, Retrofit retrofit) {
ArrayAdapter<AnItem> adapter = (ArrayAdapter<AnItem>) getListAdapter();
adapter.clear();
adapter.addAll(response.body().items);
}
Run Code Online (Sandbox Code Playgroud)
这将自动工作。
但是如果未命名json数组怎么办?
[
{"name":"foo"},
{"name":"bar"}
] …Run Code Online (Sandbox Code Playgroud) 我正在使用改造来下载一些媒体文件,如视频,mp3,jpg,pdf,...在我的应用程序中.当我想下载一个55MB格式为mp4的大文件时,这是一个问题.当我想下载此文件时,我收到如下错误:
OutOfMemoryError threw while trying to throw OutOfMemoryError; no stack trace available
Run Code Online (Sandbox Code Playgroud)
这是我的代码:
private void downloadFile() {
ArrayList<FileModel> filesInDB = G.bootFileFromFileDB();
for (final FileModel fm : filesInDB) {
APIService downloadService = ServiceGenerator.createServiceFile(APIService.class, "username", "password");
//Id of apk file that you want to download
Call<ResponseBody> call = downloadService.downloadFileWithDynamicUrlSync("file/download/" + String.valueOf(fm.getFileId()));
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccess()) {
Log.d("LOGOO", "server contacted and has file");
boolean writtenToDisk = writeResponseBodyToDisk(response.body(), fm.getFileName(), fm.getFileExtension());
response = null;
Log.d("LOGOO", "file …Run Code Online (Sandbox Code Playgroud) 我是Kotlin和 的新手Retrofit。我想打电话给基地URL通过Retrofit和打印的原始JSON响应。什么是最简单的最小配置?
让我们说,
base url = "https://devapis.gov/services/argonaut/v0/"
method = "GET"
resource = "Patient"
param = "id"
Run Code Online (Sandbox Code Playgroud)
我试过,
val patientInfoUrl = "https://devapis.gov/services/argonaut/v0/"
val infoInterceptor = Interceptor { chain ->
val newUrl = chain.request().url()
.newBuilder()
.query(accountId)
.build()
val newRequest = chain.request()
.newBuilder()
.url(newUrl)
.header("Authorization",accountInfo.tokenType + " " + accountInfo.accessToken)
.header("Accept", "application/json")
.build()
chain.proceed(newRequest)
}
val infoClient = OkHttpClient().newBuilder()
.addInterceptor(infoInterceptor)
.build()
val retrofit = Retrofit.Builder()
.baseUrl(patientInfoUrl)
.client(infoClient)
.addConverterFactory(GsonConverterFactory.create())
.build()
Logger.i(TAG, "Calling retrofit.create")
try …Run Code Online (Sandbox Code Playgroud) 我正在尝试列出来自我的服务器的呼叫,但它是空的。在邮递员上,我收到了所有列表,但我无法在 android 上制作。
我有一个模型类:
public class Model {
@SerializedName("Title")
private String Title;
@SerializedName("Price")
private BigDecimal Price;
Run Code Online (Sandbox Code Playgroud)
和来自我的界面的调用:
@GET("api/Host/GetAllEvents")
Call<List<Model>> ListAllEvents();
Run Code Online (Sandbox Code Playgroud)
我的服务等级:
@Override
public void getAllEvents(onFinishedListener onFinishedListener) {
Call<List<Model>> call = retrofitEndpoint.ListAllEvents();
call.enqueue(new Callback<List<Model>>() {
@Override
public void onResponse(@NotNull Call<List<Model>> call, @NotNull Response<List<Model>> response) {
onFinishedListener.onFinished(response.body());
}
@Override
public void onFailure(@NotNull Call<List<Model>> call, @NotNull Throwable t) {
onFinishedListener.onError(t);
}
});
}
Run Code Online (Sandbox Code Playgroud)
我收到列表大小,但属性为空。
我的改造客户端类:
private static final String BASE_URL = "http://192.168.0.101:3000";
private static Retrofit retrofit = null;
private static Gson gson = …Run Code Online (Sandbox Code Playgroud)