Ошибка MalformedJsonException с API-интерфейсом дооснастки?

Вопрос:Мне нужно отправить json на мой веб-сервис, json: { "Sala": { "usuario": "%@", "adversario": "%@", "atualizacao": "%@", "device": "%@", "device_tipo": "ios" } } . Я пытаюсь сделать это с помощью Retrofit API 1.8. При попытке отправить сообщение выдает исключение. Исключение: com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 7 path $

Вопрос:

Мне нужно отправить json на мой веб-сервис, json:

{ «Sala»: { «usuario»: «%@», «adversario»: «%@», «atualizacao»: «%@», «device»: «%@», «device_tipo»: «ios» } }

. Я пытаюсь сделать это с помощью Retrofit API 1.8.
При попытке отправить сообщение выдает исключение.

Исключение:

com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 7 path $

Я пытаюсь это сделать

public class ChatObject { private String usuario; private String adversario; private String atualizacao; private String email; private String device; private String device_tipo;

Интерфейс дооснащения

@POST(«/WsChat/interacao.json») public void onReceiveMessage(@Body ChatObject obj, Callback<JsonElement> response);

Реализует

public void receiveMessage(){ ///{«Sala»:{«usuario»:»%@»,»adversario»:»%@»,»atualizacao»:»%@»,»device»:»%@»,»device_tipo»:»ios»}} ChatObject chatObject = new ChatObject(BatalhaConfigs.USUARIO_EMAIL, BatalhaConfigs.ADVERSARIO_EMAIL, new Date().toString(), BatalhaConfigs.USUARIO_EMAIL, AndroidReturnId.getAndroidId(), «android»); RestAdapter adapter = new RestAdapter.Builder() .setLogLevel(RestAdapter.LogLevel.FULL) .setRequestInterceptor(new CustomRequestInterceptor()) .setEndpoint(END_POINT) .build(); ChatListener listener = adapter.create(ChatListener.class); listener.onReceiveMessage(chatObject, new Callback<JsonElement>() { @Override public void success(JsonElement jsonElement, retrofit.client.Response response) { Log.i(«JSON ELEMENT->», jsonElement.toString()); } @Override public void failure(RetrofitError error) { Log.i(«FALHOU->», error.getLocalizedMessage()); } }); } Лучший ответ:

com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) обычно вызывается, когда есть некоторый символ (символы), который порождает JSON. Исключительное сообщение само по себе предлагает сделать десериализацию более терпимой.

Но я предлагаю вам исправить ваш JSON и обрезать его от нежелательных символов.

Вы должны расширить GsonConverter и переопределить fromBody(), чтобы сделать Gson прочитанным из толерантного JsonReader. Затем просто установите его на RestAdapter. Это попытается использовать толерантный JsonReader для десериализации и последующего его закрытия, если не выбрано исключение.

public class LenientGsonConverter extends GsonConverter { private Gson mGson; public LenientGsonConverter(Gson gson) { super(gson); mGson = gson; } public LenientGsonConverter(Gson gson, String charset) { super(gson, charset); mGson = gson; } @Override public Object fromBody(TypedInput body, Type type) throws ConversionException { boolean willCloseStream = false; // try to close the stream, if there is no exception thrown using tolerant JsonReader try { JsonReader jsonReader = new JsonReader(new InputStreamReader(body.in())); jsonReader.setLenient(true); Object o = mGson.fromJson(jsonReader,type); willCloseStream = true; return o; } catch (IOException e) { e.printStackTrace(); }finally { if(willCloseStream) { closeStream(body); } } return super.fromBody(body, type); } private void closeStream(TypedInput body){ try { InputStream in = body.in(); in.close(); } catch (IOException e) { e.printStackTrace(); } } }

}

Ответ №1

Кажется, его немного изменили с помощью Retrofit 2.0

Вот как я это сделал:

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

Новый снимок 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); } }

Анализ продолжительности ответов:

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(); } } }

Создание запросов пользователей:

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()); } }

Я только что скопировал исходный код Retrofit и добавил строку в запрос и преобразователи откликов jsonWriter.setLenient(true);

Или еще проще:

Gson gson = new GsonBuilder() .setLenient() .create(); Retrofit retrofit = new Retrofit.Builder() .baseUrl(«http://whatever.com») .addConverterFactory(GsonConverterFactory.create(gson)) .build(); Ответ №2 RestAdapter adapterRfqPost = new RestAdapter.Builder() .setEndpoint(Constants.ENDPOINT) `enter code here`.setConverter(new ConstantsMethods.StringConverter()) .build(); public static class StringConverter implements Converter { @Override public Object fromBody(TypedInput typedInput, Type type) throws ConversionException { String text = null; try { text = fromStream(typedInput.in()); } catch (IOException ignored) {/*NOP*/ } return text; } @Override public TypedOutput toBody(Object o) { return null; } public static String fromStream(InputStream in) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(in)); StringBuilder out = new StringBuilder(); String newLine = System.getProperty(«line.separator»); String line; while ((line = reader.readLine()) != null) { out.append(line); out.append(newLine); } return out.toString(); } } Ответ №3

Я боролся около дня, чтобы получить эту ошибку и делать то, что сказал “правильный ответ” на этой странице, но в конце концов я понял свою проблему, это было назначение ответа из массива, который был “int” (также мой класс модели был int) в textView, который, конечно, потребовал от меня преобразовать его в строку со значением int. В моем случае я даже не требовал решения @Nikola Despotoski.

Ответ №4

Ниже код работал для меня

Gson gson = new GsonBuilder() .setLenient() .create(); final RestAdapter restAdapter = new RestAdapter.Builder() .setEndpoint(endPoint) .setConverter(new GsonConverter(gson)) .build();

Для использования “.setLenient()” необходимо добавить строку ниже в файл приложения.

реализация ‘com.google.code.gson: gson: 2.7’

Ответ №5

Вам следует помочь с этим кодом:

RestAdapter restAdapter = new RestAdapter.Builder() .setEndpoint(«http://192.168.10.115/test.php») .setConverter(new GsonConverter(new Gson())) .build();

Поместить файл jar:

[gson-2.2.2.jar][1]

Оцените статью
Добавить комментарий