Дженсон с JsonBindingException в Джерси: не удалось десериализовать тип java.lang.String

В моем Java-приложении Spring MVC я использую Jersey REST API. Я использую Джексона для обработки JSON. Я добавил Дженсона в свой проект для фильтрации некоторых полей для некоторых классов. И я пытаюсь использовать Дженсона только для этого, и в остальном я хочу использовать Джексона.

Но я получаю исключение, когда использую API-интерфейс Jersey REST, поскольку Джерси активировал Genson по умолчанию, когда Jar находится в classpath ( узнайте по этой ссылке).

Вот мой код в подключиться к веб-сервису и получить данные и преобразовать в строку с помощью Джексона

public String connect() throws Exception {
        Client client = Client.create();
        try {
            String auth = new String(Base64.encode(userName + COLON + password));
            WebResource webResource = client
                    .resource(webServiceUrl);
            ClientResponse response = webResource
                    .header(AUTHORIZATION, BASIC + auth).type(APPLICATION_JSON)
                    .accept(APPLICATION_JSON).get(ClientResponse.class);
            //code to check response status code.
                stringResponse = response.getEntity(String.class);

        } catch (ClientHandlerException e) {
            throw new Exception("Not a Valid Url.");
        } finally {
            client.destroy();
        }
        return stringResponse;
}

Я получаю следующее исключение

javax.ws.rs.WebApplicationException: com.owlike.genson.JsonBindingException: Could not deserialize to type class java.lang.String
    at com.owlike.genson.ext.jaxrs.GensonJsonConverter.readFrom(GensonJsonConverter.java:130)
    at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:553)
    at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:506)
    at com.myapp.WebHttpClient.connect(WebHttpClient.java:74)
    at com.myapp.connection.connectors.WebConnector.getData(WebConnector.java:39)
    at com.myapp.adapter.impl.SourceAdapter.getData(SourceAdapter.java:29)
    at com.myapp.service.impl.WebServiceImpl.adapter(WebServiceImpl.java:174)
    at com.myapp.service.impl.WebServiceImpl.connect(WebServiceImpl.java:107)
    ... 41 more
Caused by: com.owlike.genson.JsonBindingException: Could not deserialize to type class java.lang.String
    at com.owlike.genson.Genson.deserialize(Genson.java:398)
    at com.owlike.genson.ext.jaxrs.GensonJsonConverter.readFrom(GensonJsonConverter.java:128)
    ... 48 more
Caused by: com.owlike.genson.stream.JsonStreamException: Readen value can not be converted to String
    at com.owlike.genson.stream.JsonReader.valueAsString(JsonReader.java:200)
    at com.owlike.genson.convert.DefaultConverters$StringConverter.deserialize(DefaultConverters.java:364)
    at com.owlike.genson.convert.DefaultConverters$StringConverter.deserialize(DefaultConverters.java:351)
    at com.owlike.genson.convert.NullConverter$NullConverterWrapper.deserialize(NullConverter.java:56)
    at com.owlike.genson.Genson.deserialize(Genson.java:396)
    ... 49 more

Строка 74 относится к stringResponse = response.getEntity(String.class);,

Как отключить Genson for Jersey или Как решить эту проблему с помощью Genson?

Спасибо

1 ответ

Решение

Актуальная документация Genson размещена на github http://owlike.github.io/genson/.

Что на самом деле происходит

Мне не понятно, где вы хотите использовать Genson и как. Вы используете Genson только для сериализации? Вы используете его через майку или напрямую?

Когда вы делаете getEntity(String.class), Джерси просит Генсона дезертировать входящий json в строку. Обратите внимание, что в общем формате json строки не допускаются в качестве корневых значений.

Решения

  1. Обновление до версии 2.X (и последней версии Genson), в новой версии на Джерси, когда вы запрашиваете ввод как строку, он не делегируется MessageBodyReader (правильное поведение IMO). Затем вы можете использовать эту строку, чтобы дезертировать в любой тип, который вы хотите.

  2. Используйте метод getEntityInputStream из ClientResponse, чтобы получить необработанный InputStream и преобразовать его в строку.

  3. Другим решением было бы переопределить реализацию MessageBodyReader для Gensons, чтобы не обрабатывать deser для String.


Наличие нескольких библиотек, одновременно обрабатывающих преобразование JSON, мне не подходит. Тем более, что оба (Джексон и Генсон) предоставляют некоторые похожие функции. Я открыл проблему, позволяющую людям отключать Genson в приложениях JAX-RS.

Обновите Genson 1.3 и выше, предоставьте систему для отключения Genson в приложении Jax-RS.

Вот пример решения 2...

Используйте метод getEntityInputStream из ClientResponse, чтобы получить необработанный InputStream и преобразовать его в String:

private String responseString(ClientResponse response) {
    InputStream stream = response.getEntityInputStream();
    StringBuilder textBuilder = new StringBuilder();
    try (Reader reader = new BufferedReader(new InputStreamReader(stream, Charset.forName(StandardCharsets.UTF_8.name())))) {
        int c = 0;
        while ((c = reader.read()) != -1) {
            textBuilder.append((char) c);
        }
        return textBuilder.toString();
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
}
Другие вопросы по тегам