Retrofit ratings about Retrofit and retrofit ratings

Source: Internet
Author: User

Retrofit ratings about Retrofit and retrofit ratings
Advantages

Programming philosophy: reduce decoupling and coupling, and make the development of interfaces flexible. Different APIs do not interfere with each other,

Code style: simple, easy to understand and use with annotations

Design Philosophy: the builder mode is used for easy development and construction!

For more information, see the previous articles! Let's talk about the problem today. At least I think the egg pains is not enough!

General problems

1 url escaped

   http://api.myapi.com/http%3A%2F%2Fapi.mysite.com%2Fuser%2Flist

Change @ path to @ url

   public interface APIService {     @GET Call
 
   getUsers(@Url String url);}
 

Or:

  public interface APIService {    @GET("{fullUrl}")    Call
 
   getUsers(@Path(value = "fullUrl", encoded = true) String fullUrl);}
 

Method not found

Java. lang. IllegalArgumentException: Method must not be null

Please specify the specific request type @ get @ post, etc.

   public interface APIService {    @GET Call
 
   getUsers(@Url String url);}
 

The Url is incorrectly encoded. @ fieldMap parameters must be use FormUrlEncoded

If you use fieldMap with FormUrlEncoded encoding

@POST()@FormUrlEncodedObservable
 
   executePost(        @FieldMap Map
  
    maps);
  
 

The upper layer needs to convert its map to FieldMap.

 @FieldMap(encoded = true) Map
 
   parameters,
 

4. Use paht and url together

Using @ Path and @ Url paramers together with login fit2

Java. lang. IllegalArgumentException: @ Path parameters may not be used with @ Url. (parameter #4

If you do:

 @GETCall
 
   getOrder(@Url String url, @Path("id") int id);
 

Specify the placeholder. url in your url:

www.mylist.com/get{Id}
Unsupported or the defective Url cannot be blank

Does my scenario require a fixed domain to be dynamic? Sometimes I use www.myapi.com or www.youapi.com. So I decided not to add baseUrl when building the Dynamic Fit;

Retrofit retrofit = new Retrofit.Builder()        .addConverterFactory(GsonConverterFactory.create())        .build();

An exception is reported.

Base URL required

Check Url during construction is found in the source code. If it is null, an exception occurs.

public Retrofit build() {  if (baseUrl == null) {    throw new IllegalStateException("Base URL required.");  }

Later, although it is a good solution for dynamic Url modification@ Url instead, but I do not know why it is necessary to limit it!

@GET
Call getOrder(@Url String url,
@Path(“id”) int id);

Delete does not support body

Retrofit @Delete with body,Non-body HTTP method cannot contain @Body ##

The background interface will definitely be in the body format when using the deletefit for delete request!
As a result, I happily defined the interface:

@DELETE("/user/delete")Call
  
    remove (@Body HashMap
   
     content);
   
  

The result is blinded by an exception:

java.lang.IllegalArgumentException:Non-body HTTP method cannot contain @Body

The official website finds that it does not support transferring the body to the server. This exception is reported.java.lang.IllegalArgumentException:Non-body HTTP method cannot contain @Body ,

The author of gtihub also said that it does not support the body, and finally found that the answer uses a custom annotation. If you need to transmit the body to the server, you can write it like this.

@HTTP(method = "DELETE",path = "/user/delete",hasBody = true)Call  remove (@Body HashMap  content);  
Interface instance does not support T

Every time we use retrofit to execute a network request, we must define an ApiServie, and a specific instance must be added to the interface!

public interface ApiService {@GETCall  get(@Url String url, @Query("id") int id);} 

Then we will build an apiService instance!

Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://localhost:8080/") .addConverterFactory(GsonConverterFactory.create()) .build();

Build Api

ApiServicer apiService = retrofit.create(ApiService.class);

Developers often want to write a baseApiService for a large number of interfaces, and then inherit the baseApiService from the APIs of different modules, so they will inherit to build a baseService according to the conventional aop idea, other sub-classes implement this method. Let's take a look at the following method. The specific returned object is written as T, which is OK!

public interface BaseApiService {@GETCall  get(@Url String url, @Path("id") int id);} 

When I encounter a login and exit scenario, I don't want to write it into an ApiService. It is very likely that I want to build a loginApiService and LoginOutApiService:

public class loginApiService implements BaseApiService {@GETCall  get(@Url String url, @Query("id") int id) { // ......} }ApiServicer apiService = retrofit.create(loginApiService.class); 

The result is wrong. My God! Is there something wrong with me? I wrote an interface and used implementation classes to execute it. Does java tell me this is not feasible. Blinded, throwing an exception!

API declarations must be interfaces.

Source code:

static  void validateServiceInterface(Class  service) {if (!service.isInterface()) { throw new IllegalArgumentException("API declarations must be interfaces.");}  

The good author's intention is obviously to use the interface type. You can use the interface, so I will follow it!

public interface loginApiService extends BaseApiService {@GETCall  get(@Url String url, @Query("id") int id) } 

Result:

T is not a valid response body type. Did you mean ResponseBody?

I felt that I had to solve the problem. I forced to change the returned value of the parent class and thought it could pass!

public interface loginApiService extends BaseApiService {

@GETCall  get(@Url String url, @Query("id") int id) } 

The results are not compiled. My God! I don't need to use generics. I started to get overwhelmed. Does it mean that I have to write an Api method for each request interface? Although it is solved by reflection, I really want to say: nnD

I have:

@GETCall  get(@Url String url, @Map  mapsid) }  

In this way, I can use an interface to log on and log out, but every time the returned object needs to be parsed by myself, the reflection is used.

 private List  MethodHandler(Type[] types) { Log.d(TAG, "types size: " + types.length); List  needtypes = new ArrayList<>(); Type needParentType = null; for (Type paramType : types) { // if Type is T if (paramType instanceof ParameterizedType) { Type[] parentypes = ((ParameterizedType) paramType).getActualTypeArguments(); for (Type childtype : parentypes) { needtypes.add(childtype); if (childtype instanceof ParameterizedType) { Type[] childtypes = ((ParameterizedType) childtype).getActualTypeArguments(); for (Type type : childtypes) { needtypes.add(type); //needChildType = type; Log.d(TAG, "type:" + childtype); } } } } } return types;}  

Then I deserialize the object in the successful callback of IFT:

 User user = new Gson().fromJson(ResponseBody.body.toString(), mType);

MType is the user object passed in from the upper layer that I reflected. Nima, I really don't know why the author designed it like this. egg pains

The parameter cannot be blank.

I don't want to talk about the problem above. Now I can't stand it. For example, we define an api

@GET("/path")Call  get( @QueryMap  mapsid) }  

I designed it to make it possible for the upper layer to be dynamically miserable, and this parameter may not be fixed.

When constructing parameters:

 Map  parameters = new HashMap<>(); parameters.put("apikey", "27b6fb21f2b42e9d70cd722b2ed038a9"); parameters.put("Accept", "application/json"); 

There is no problem with running the program and the api results. At this point, I thought all the parameters can be added, so I used this solution in the next login-free scenario. token is the string returned by the server. Each request is added without local access. For the first time, the request is certainly unavailable. construction parameters:

 Map  parameters = new HashMap<>(); parameters.put("token", getToken()); parameters.put("Accept", "application/json"); 

Build:

 Call  call = apiService.get(parameters ); call.enqueue(new Callback  () { @Override public void onResponse(Call  call, Response  response) { } @Override public void onFailure(Call  call, Throwable t) { }     

When the result is running, I run the re command. In this case, an error is returned, indicating that the token cannot be empty. Is it true that the value cannot be empty when I am not sure about a value? I have to build the parameter in the following way,

 Map  parameters = new HashMap<>(); parameters.put("token", getToken() == Null?gettoken() :" " ); parameters.put("Accept", "application/json"); 

Finally, the source code is read.@ QueryMap k-v cannot be blank. Okay, I'm drunk!

Default interception exception

Retrofit intercepts Okhttp default error. If the web side is normal msg information when the code is 200 or 300 by default, onResponse () is used ().

If the success Code defined by the web is <200 and> 300, it will not succeed. If the defined result code of the server conflicts with the default int of the system, the custom msg cannot be called back to onError, the message of the super Throw is automatically obtained by retrofit.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.