MalformedJsonException with Retrofit API?

后端 未结 7 793
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-01 14:18

I need send a json to my webservice, json is:

{
    \"Sala\": {
        \"usuario\": \"%@\",
        \"adversario\": \"%@\",
        \"atualizacao\": \"%@\"         


        
相关标签:
7条回答
  • 2020-12-01 15:18

    Seems its changed slightly with Retrofit 2.0

    Here's how I did it:

     Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("http://whatever.com")
            .addConverterFactory(LenientGsonConverterFactory.create(gson))
            .build();
    

    A new lenient gson factory:

    public final class LenientGsonConverterFactory extends Converter.Factory {
    
            /**
             * Create an instance using a default {@link Gson} instance for conversion. Encoding to JSON and
             * decoding from JSON (when no charset is specified by a header) will use UTF-8.
             */
            public static LenientGsonConverterFactory create() {
                return create(new Gson());
            }
    
            /**
             * Create an instance using {@code gson} for conversion. Encoding to JSON and
             * decoding from JSON (when no charset is specified by a header) will use UTF-8.
             */
            public static LenientGsonConverterFactory create(Gson gson) {
                return new LenientGsonConverterFactory(gson);
            }
    
            private final Gson gson;
    
            private LenientGsonConverterFactory(Gson gson) {
                if (gson == null) throw new NullPointerException("gson == null");
                this.gson = gson;
            }
    
            @Override
            public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
                                                                    Retrofit retrofit) {
                TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
                return new LenientGsonResponseBodyConverter<>(gson, adapter);
            }
    
            @Override
            public Converter<?, RequestBody> requestBodyConverter(Type type,
                                                                  Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
                TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
                return new LenientGsonRequestBodyConverter<>(gson, adapter);
            }
    
        }
    

    Lenient parsing of responses:

        private class LenientGsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
            private final Gson gson;
            private final TypeAdapter<T> adapter;
    
            LenientGsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter) {
                this.gson = gson;
                this.adapter = adapter;
            }
    
            @Override
            public T convert(ResponseBody value) throws IOException {
                JsonReader jsonReader = gson.newJsonReader(value.charStream());
                jsonReader.setLenient(true);
                try {
                    return adapter.read(jsonReader);
                } finally {
                    value.close();
                }
            }
        }
    

    Lenient creation of requests:

       private class LenientGsonRequestBodyConverter<T> implements Converter<T, RequestBody> {
            private static final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8");
            private static final Charset UTF_8 = Charset.forName("UTF-8");
    
            private final Gson gson;
            private final TypeAdapter<T> adapter;
    
            LenientGsonRequestBodyConverter(Gson gson, TypeAdapter<T> adapter) {
                this.gson = gson;
                this.adapter = adapter;
            }
    
            @Override
            public RequestBody convert(T value) throws IOException {
                Buffer buffer = new Buffer();
                Writer writer = new OutputStreamWriter(buffer.outputStream(), UTF_8);
                JsonWriter jsonWriter = gson.newJsonWriter(writer);
                jsonWriter.setLenient(true);
                adapter.write(jsonWriter, value);
                jsonWriter.close();
                return RequestBody.create(MEDIA_TYPE, buffer.readByteString());
            }
        }
    

    I just copied the Retrofit source code and added a line to the request and the response converters jsonWriter.setLenient(true);


    Or even easier:

        Gson gson = new GsonBuilder()
            .setLenient()
            .create();
    
        Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("http://whatever.com")
            .addConverterFactory(GsonConverterFactory.create(gson))
            .build(); 
    
    0 讨论(0)
提交回复
热议问题