Custom BeanPropertyFilter - только сериализация части строки

Я остро нуждаюсь в помощи. В настоящее время я делаю некоторые ограничения безопасности для ресурса в Content API, где мне нужно либо: включить свойства, усечь свойства (если они являются String.class) или удалить свойства из объекта сериализации на основе SecurityContext.

Я использую Джексона как мой сериализатор json и решил использовать BeanPropertyFilter, чтобы проверить, должно ли каждое свойство быть сериализованным или нет.

Теперь параметры удаления и включения довольно просты: я сериализую компонент или нет.

Но вариант усечения немного хуже. Итак, вот что я сделал до сих пор в отношении сериализации свойства.

@Override
public void serializeAsField(Object bean, JsonGenerator jgen, SerializerProvider provider, BeanPropertyWriter writer) throws Exception {
    switch (determineFilterAction(writer)) {
        case INCLUDE_UNMODIFIED:
            writer.serializeAsField(bean, jgen, provider);
            break;
        case INCLUDE_TRUNCATED:
            Object value = writer.get(bean);
            if (!(value instanceof String)) {
                throw new UnsupportedOperationException("Annotation indicates truncate on " + writer.toString() + " which is not a string, but a " + value.getClass().getSimpleName() + " and is unsupported");
            }
            JsonSerializer oldSerialzer= writer.getSerializer();
            writer.assignSerializer(new TruncateStringJsonSerializer());
            writer.serializeAsField(bean, jgen, provider);
            writer.assignSerializer(oldSerialzer);
            break;
        case REMOVE:
            // do nothing
            break;
    }
}

Проблема в том, что в методе BeanPropertyWriter.assignSerializer() есть защита, которая не позволяет мне переключать новый настраиваемый сериализатор для этого одного свойства.

Есть ли способ подключиться и изменить значение бина? Или мне придется переопределить фабрики и BeanPropertyWriter, чтобы переопределить метод assignSerializer () (чтобы избежать защиты сериализатора)?

Я не могу просто аннотировать свои свойства с помощью специального средства записи, поскольку объект сериализации ничего не знает о SecurityContext, поэтому нет способа внедрить securityContext в пользовательский сериализатор.

Есть ли какой-нибудь способ сделать этот вариант усечения (не делая его слишком хакерским)?

Заранее спасибо.

// С наилучшими пожеланиями, Мартин.

ОБНОВИТЬ

Основываясь на ответе StaxMan, я обновил метод, чтобы он выглядел следующим образом, и, похоже, он работает. По крайней мере, все мои тесты выполняются правильно. Далее будем тестировать на разработке приложений-серверов.

@Override
public void serializeAsField(Object bean, JsonGenerator jgen, SerializerProvider provider, BeanPropertyWriter writer) throws Exception {
    switch (determineFilterAction(writer)) {
        case INCLUDE_UNMODIFIED:
            writer.serializeAsField(bean, jgen, provider);
            break;
        case INCLUDE_TRUNCATED:
            Object value = writer.get(bean);
            if (!(value instanceof String)) {
                throw new UnsupportedOperationException("Annotation indicates truncate on " + writer.toString() + " which is not a string, but a " + value.getClass().getSimpleName() + " and is unsupported");
            }
            String valueString = (String) value;
            jgen.writeFieldName(writer.getName());
            jgen.writeString(StringUtils.abbreviate(valueString, MAX_LENGTH));
            break;
        case REMOVE:
            // do nothing
            break;
    }
}

1 ответ

Решение

Нет, даже не пытайся позвонить assignSerializerЭто плохая идея в многопоточной среде - есть только один экземпляр этого сериализатора, и даже если бы вы могли его вызвать, он просто вызвал бы странное исключение в случаях, когда две сериализации выполнялись одновременно.

Но, возможно, вам следует рассмотреть этот подход с другой стороны: поскольку вы уже находите String значение, почему бы не записать усеченное значение напрямую, используя JsonGenerator? Или, если вы предпочитаете, делегируйте что-то, что делает запись; но так как вы называете это, это не должно быть JsonSerializer или что-нибудь.

Другие вопросы по тегам