Как исправить ошибку декодирования JSON в Spring?

Я отправляю объект пользователя через REST, который содержит набор объектов SimpleGrantedAuthority. На стороне получателя я получаю исключение:

org.springframework.core.codec.DecodingException: ошибка декодирования JSON: невозможно создать экземпляр org.springframework.security.core.authority.SimpleGrantedAuthority (хотя существует по крайней мере один Creator): невозможно десериализовать из значения объекта (без делегата или создателя на основе свойств);

Я использую сопоставитель JSON по умолчанию, который предоставляет Spring Boot 2.1.2. На принимающей стороне я использую WebClient WebFlux (в данном случае WebTestClient).

Может ли кто-нибудь объяснить мне, почему я получаю эту ошибку и как ее решить?


person OCPi    schedule 15.01.2019    source источник
comment
stackoverflow.com/questions/47570931/   -  person xingbin    schedule 15.01.2019


Ответы (1)


SimpleGrantedAuthority не подходит для автоматического сопоставления с Джексоном; у него нет конструктора без аргументов и нет установщика для поля authority.

Поэтому ему нужен собственный десериализатор. Что-то вроде этого:

class SimpleGrantedAuthorityDeserializer extends StdDeserializer<SimpleGrantedAuthority> {
    public SimpleGrantedAuthorityDeserializer() {
        super(SimpleGrantedAuthority.class);
    }
    @Override
    public SimpleGrantedAuthority deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        JsonNode tree = p.getCodec().readTree(p);
        return new SimpleGrantedAuthority(tree.get("authority").textValue());
    }
}

Зарегистрируйте его в Jackson глобально следующим образом:

objectMapper.registerModule(new SimpleModule().addDeserializer(
                      SimpleGrantedAuthority.class, new SimpleGrantedAuthorityDeserializer()));

Или аннотируйте поля с помощью:

@JsonDeserialize(using = SimpleGrantedAuthorityDeserializer.class)

Примечание: вам не нужен сериализатор, потому что SimpleGrantedAuthority имеет метод getAuthority(), который может использовать Джексон.

person rustyx    schedule 15.01.2019
comment
Большое спасибо! Работает как шарм. - person OCPi; 16.01.2019