android - Retrofit2: serializer doesn't get called for @Field-annotated parameters -


i need send http put request custom json object in 1 of request's parameter. here problem: when use retrofit2, serializer doesn't called.

my object should looks this:

{     "ignore":["item1", "item2"] } 

when call directly works well:

final gson gson = new gsonbuilder()         .registertypeadapter(mymodel.class, new mymodelserializer())         .create(); string s = gson.tojson(new mymodel(mymodel.actionname.accept, new arraylist<string>())); log.d("tag", s); 

i {"accept":[]}. when call retrofit see in logs this: d/okhttp: name=abc&items=ru.bartwell.myapp.mymodel%4010a3d8b

i make request code:

try {     mymodel mymodel = new mymodel(mymodel.actionname.accept, new arraylist<string>());     response<resultmodel> response = getmyapi().getresult(1, "abc", mymodel).execute();     if (response.issuccessful()) {         resultmodel resultmodel = response.body();         // handle resultmodel     } } catch (exception e) {     e.printstacktrace(); } 

myapi:

@formurlencoded @put("path/{id}") call<resultmodel> getresult(@path("id") long item, @field("name") @nonnull string name, @field("items") @nonnull mymodel mymodel); 

getmyapi() method:

public static myapi getmyapi() {     final gson gson = new gsonbuilder()         .registertypeadapter(mymodel.class, new mymodelserializer())         .create();      return new retrofit.builder()             .baseurl(buildconfig.end_point_my_api)             .client(myokhttpclient.create())             .addconverterfactory(gsonconverterfactory.create(gson))             .build()             .create(myapi.class); } 

model:

public class mymodel {     @nonnull     private actionname mactionname;     @nonnull     private list<string> mitems = new arraylist<>();      public mymodel(@nonnull final actionname actionname, @nonnull final list<string> items) {         mactionname = actionname;         mitems = items;     }      @nonnull     public actionname getactionname() {         return mactionname;     }      @nonnull     public list<string> getitems() {         return mitems;     }      public enum actionname {         accept("accept"), decline("decline"), ignore("ignore");          private string mname;          actionname(@nonnull final string name) {             mname = name;         }          public string getname() {             return mname;         }     } } 

serializer:

public class mymodelserializer implements jsonserializer<mymodel> {     @override     public jsonelement serialize(@nonnull mymodel src, @nonnull type typeofsrc, @nonnull jsonserializationcontext context) {         jsonobject obj = new jsonobject();         obj.add(src.getactionname().getname(), new gson().tojsontree(src.getitems()));         return obj;     } } 

how fix it?

this happens because @field-annotated parameters serialized stringconverter. override default behavior, need add converter.factory stringconverter method overridden:

.addconverterfactory(new converter.factory() {     @override     public converter<?, string> stringconverter(final type type, final annotation[] annotations, final retrofit retrofit) {         // example check supported classes         if ( type instanceof class ) {             final class<?> clazz = (class<?>) type;             if ( mymodel.class.isassignablefrom(clazz) ) {                 return (converter<object, string>) value -> gson.tojson(value, type);             }         }         return super.stringconverter(type, annotations, retrofit);     } }) 

then query parameter string this:

name=abc&items=%7b%22accept%22%3a%5b%5d%7d

(this %7b%22accept%22%3a%5b%5d%7d' uri-encoded {"accept":[]}).

a few side-notes:

  • gson instances thread-safe , can created once per whole application (and fine pass single instance components).
  • your mymodelserializer can improved: should not create gson instance there since deserializers bound gson instance configuration, have delegate serialization via given context context.serialize(mymodel.mitems, itemstype), itemstype new typetoken<list<string>>() {}.gettype().

Comments

Popular posts from this blog

Command prompt result in label. Python 2.7 -

javascript - How do I use URL parameters to change link href on page? -

amazon web services - AWS Route53 Trying To Get Site To Resolve To www -