Запрет сериализации дерева компонентов для определенных частей приложения

Можно ли явно запретить JSF сериализацию некоторых деревьев компонентов? В данный момент я передаю несериализуемый объект <h:inputText>:

<h:inputText value="#{nonSerializableBean.nonSerializableClassInstance}" />

Что происходит после нескольких кликов, так это то, что я получаю (во время восстановления представления):

javax.faces.FacesException: Unexpected error restoring state for component
with id configurationForm:j_idt292:j_idt302:field.  Cause:
java.lang.IllegalStateException: java.lang.InstantiationException:
my.namespace.NonSerializableClass

Я думаю, что это происходит потому, что JSF не может восстановить nonSerializableClassInstance:

Caused by: java.lang.IllegalStateException: java.lang.InstantiationException: com.foobar.utils.text.Period
at javax.faces.component.StateHolderSaver.restore(StateHolderSaver.java:110)
at javax.faces.component.ComponentStateHelper.restoreState(ComponentStateHelper.java:292)
at javax.faces.component.UIComponentBase.restoreState(UIComponentBase.java:1444)
at javax.faces.component.UIOutput.restoreState(UIOutput.java:255)
at javax.faces.component.UIInput.restoreState(UIInput.java:1359)

Дополнительный вопрос: можно ли не делать поддерживающие бобы Serializable? Должно ли это предотвратить сериализацию / десериализацию этих файлов?

Немного предыстории:

У нас есть куча сторонних классов, для которых нам нужно предоставить формы в JSF. Проблема в том, что мы не можем напрямую использовать эти классы на страницах JSF, потому что они не реализуют интерфейс Serializable и, таким образом, потерпят / должны потерпеть неудачу, если среда выполнения JSF решит сериализовать / десериализовать страницу и дерево компонентов. Классы "закрыты", и мы не можем их изменять.

Запуск Мохарры 2.0.2.

2 ответа

Решение

Javabeans по спецификации должны реализовать Serializable, JSF просто следует / придерживается этой спецификации.

Классы "закрыты", и мы не можем их изменять.

Лучше всего обернуть его как transient свойство класса, который реализует Serializable и реализовать writeObject() а также readObject() соответственно.

public class SerializableClass implements Serializable {

    private transient NonSerializableClass nonSerializableClass;

    public SerializableClass(NonSerializableClass nonSerializableClass) {
        this.nonSerializableClass = nonSerializableClass;
    }

    public NonSerializableClass getNonSerializableClass() {
        return nonSerializableClass;
    }

    private void writeObject(ObjectOutputStream oos) throws IOException {
        oos.defaultWriteObject();
        oos.writeObject(nonSerializableClass.getProperty1());
        oos.writeObject(nonSerializableClass.getProperty2());
        // ...
    }

    private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
        ois.defaultReadObject();
        nonSerializableClass = new NonSerializableClass();
        nonSerializableClass.setProperty1((String) ois.readObject());
        nonSerializableClass.setProperty2((String) ois.readObject());
        // ...
    }

}

Наконец, вместо этого используйте этот класс. Вы могли бы в конечном итоге позволить это extends NonSerializableClass и затем автоматически генерировать методы делегата с помощью немного приличной IDE.

В любом случае, это будет только много непрозрачного и стандартного кода, но так как вам не разрешено изменять эти классы... (Я бы лично подтолкнул эти сторонние материалы, чтобы они могли реализовать их так называемые Javabeans Serializable так как именно они нарушают стандарты / спецификации).

Я не знаю, что вы ожидаете, если ученики (например, nonSerializableClassInstance) не получают сериализацию. Конечно, вы можете пометить их как transient,

Целью управляемого компонента является сохранение состояния приложения - вы потеряете это состояние, если некоторые члены не будут сериализованы (если сервер будет нуждаться в этом).

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