ViewScoped bean не воссоздается при навигации с actionListener [duplicate]

Что вам не хватает, так это то, что hash.update() не заменяет хешированные данные. Вы постоянно обновляете хэш-объект, так что вы получаете хэш из конкатенированных строк . Из документации hashlib.hash.update() :

Обновите хэш-объект со строкой arg . Повторные вызовы эквивалентны одному вызову с конкатенацией всех аргументов: m.update(a); m.update(b) эквивалентен m.update(a+b).

blockquote>

Смелый акцент мой.

Итак, вы не получаете хеш одной строки 'stackoverflow', вы получаете хэш сначала из 'stackoverflow', затем из 'stackoverflowstackoverflow', затем 'stackoverflowstackoverflowstackoverflow' и т. д., каждый раз, когда добавляет другой 'stackoverflow', создавая более длинную и длинную строку. Ни одна из этих более длинных строк не равна исходной короткой строке, поэтому их хэши вряд ли будут одинаковыми.

Создайте новый объект new для новых строк:

>>> import hashlib
>>> m = hashlib.md5()
>>> m.update('stack' + 'overflow')
>>> m.hexdigest()
'73868cb1848a216984dca1b6b0ee37bc'
>>> m = hashlib.md5()   # **new** hash object
>>> m.update('stackoverflow')
>>> m.hexdigest()
'73868cb1848a216984dca1b6b0ee37bc'
>>> m = hashlib.md5()     # new object again
>>> m.update('stack')     # add the string in pieces, part 1
>>> m.update('overflow')  # and part 2
>>> m.hexdigest()
'73868cb1848a216984dca1b6b0ee37bc'

Вы можете легко создать свои «неправильные» хэши, отправив в конкатенированные данные:

>>> m = hashlib.md5()
>>> m.update('stackoverflowstackoverflow')
>>> m.hexdigest()
'458b7358b9e0c3f561957b96e543c5a8'
>>> m = hashlib.md5()
>>> m.update('stackoverflowstackoverflowstackoverflow')
>>> m.hexdigest()
'65b0e62d4ff2d91e111ecc8f27f0e8f5'
>>> m = hashlib.md5()
>>> m.update('stackoverflow' * 4)
>>> m.hexdigest()
'60c3ae3dd9a2095340b2e024194bad3c'

Обратите внимание, что вы также можете передать первую строку в функцию md5():

>>> hashlib.md5('stackoverflow').hexdigest()
'73868cb1848a216984dca1b6b0ee37bc'

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

355
задан BalusC 15 November 2013 в 14:02
поделиться

3 ответа

530
ответ дан Community 22 August 2018 в 18:35
поделиться

Как указано BalusC, actionListener по умолчанию использует исключение, но в JSF 2.0 есть немного больше. А именно, он не просто проглатывает и записывает журналы, а фактически публикует исключение.

Это происходит с помощью такого вызова:

context.getApplication().publishEvent(context, ExceptionQueuedEvent.class,                                                          
    new ExceptionQueuedEventContext(context, exception, source, phaseId)
);

Слушателем по умолчанию для этого события является ExceptionHandler, который для Моджары установлен на com.sun.faces.context.ExceptionHandlerImpl. Эта реализация в основном отменяет любое исключение, за исключением случаев, когда это относится к исключению AbortProcessingException, которое регистрируется. ActionListeners обертывают исключение, которое генерируется клиентским кодом в таком AbortProcessingException, которое объясняет, почему они всегда регистрируются.

Этот ExceptionHandler может быть заменен, однако, в faces-config.xml с пользовательской реализацией:

<exception-handlerfactory>
   com.foo.myExceptionHandler
</exception-handlerfactory>

Вместо того, чтобы слушать глобально, один компонент может также слушать эти события. Ниже приведено доказательство этой концепции:

@ManagedBean
@RequestScoped
public class MyBean {

    public void actionMethod(ActionEvent event) {

        FacesContext.getCurrentInstance().getApplication().subscribeToEvent(ExceptionQueuedEvent.class, new SystemEventListener() {

        @Override
        public void processEvent(SystemEvent event) throws AbortProcessingException {
            ExceptionQueuedEventContext content = (ExceptionQueuedEventContext)event.getSource();
            throw new RuntimeException(content.getException());
        }

        @Override
        public boolean isListenerForSource(Object source) {
            return true;
        }
        });

        throw new RuntimeException("test");
    }

}

(обратите внимание: это не то, как обычно нужно кодировать слушателей, это только для демонстрационных целей!) [/ ​​G0]

Вызов этого из Facelet следующим образом:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core">
    <h:body>
        <h:form>
            <h:commandButton value="test" actionListener="#{myBean.actionMethod}"/>
        </h:form>
    </h:body>
</html>

Будет отображаться страница с ошибкой.

44
ответ дан Arjan Tijms 22 August 2018 в 18:35
поделиться

Сначала запускается ActionListener с возможностью изменения ответа, прежде чем действие вызывается и определяет местоположение следующей страницы.

Если у вас несколько кнопок на одной странице, которые должны перейти в в том же месте, но делайте несколько разные вещи, вы можете использовать одно и то же действие для каждой кнопки, но использовать другой ActionListener для обработки немного разных функций.

Вот ссылка, которая описывает взаимосвязь:

http://www.java-samples.com/showtutorial.php?tutorialid=605

37
ответ дан Erick Robertson 22 August 2018 в 18:35
поделиться
  • 1
    плюс один, Жирные буквы говорят почти все. – Shirgill Farhan Ansari 26 December 2014 в 13:40
Другие вопросы по тегам:

Похожие вопросы: