Подтвердить что ты не робот

Как передать сырой JSON через Джексона?

У нас есть целый набор сервисов JAX-RS REST, работающих поверх Apache CXF и Jackson. Мы используем аннотации JAXB, чтобы заботиться о сортировке POJO для JSON, отлично работает.

Однако у нас есть одно или два места, где мы хотим вернуть необработанную строку JSON (которую мы извлекаем из кеша Redis).

Джексон всегда переносит строку в двойные кавычки и пропускает все двойные кавычки в ней, например.

@GET @Produces("application/json")
public Response getData() {

    String json = ...get from Redis...
    return Response.ok(json,"application/json").build() 
}

дает нам

"{\"test\":1}"

вместо

{"test":1}

Я пробовал несколько вещей, добавляя RawSerializer (String.class) к объекту Mapper, ничего не работает. Единственное, что работает, - это установить тип носителя в обычную строку, которая обошла Джексона, но это не хорошо, поскольку я возвращаю неправильный тип содержимого

то есть.

return Response.ok(json,"text/plain").build() 

работает, но плохо (неправильный тип контента, который закручивает приложения .Net WCF, которые нас называют)

4b9b3361

Ответ 1

Наконец-то нашел решение. Трюк состоял в том, чтобы расширить JacksonJsonProvider (который мы используем в CXF, чтобы заставить его использовать Джексона вместо Jettison) и сказать ему обходить Джексона вообще при работе с raw Strings:

public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType){
    if (String.class.equals(type)) {
        //pass strings as-is, they are most likely cached JSON responses
        return false;
    } else {
        return true;
    }
}

Работает отлично.

Ответ 2

ObjectMapper не работает? Должно быть только:

ObjectMapper mapper = new ObjectMapper()
MyObj obj = MyObj();
...set values...
String jsonRes = mapper.writeValueAsString(obj);
return Response.ok(jsonRes, MediaType.APPLICATION_JSON).build();

Ответ 3

В таком случае лучше всего использовать тип возврата String, так как проблема не с Джексоном - чья задача заключается в том, чтобы выпустить JSON из объектов, а не передавать строки как есть, - но с JAX- RS, который не должен называть Джексона. По умолчанию Jackson-backed JSON-провайдер будет передавать значение String точно так же, как и (titto для byte[]), без какой-либо обработки.

Для того, что стоит, есть и метод JsonGenerator.writeRaw(), который позволяет вставлять литеральный текст в OutputStream, но реализации JAX-RS используют ObjectMapper, а не абстракции низкого уровня.