2012-01-31 3 views
16

Я использую JSF 2.0 с GlassFish 3.0.Метод @PostConstruct, вызываемый дважды для одного запроса

Я следующее Managed Bean:

@ManagedBean 
@RequestScoped 
public class OverviewController{ 

    private List<Event> eventList; 

    @PostConstruct 
    public void init(){ 
     System.out.println("=> OverviewController - init() - enter"); 

     System.out.println("=< OverviewController - init() - exit"); 
    } 
} 

Из файла в overview.xhtml Я звоню различные атрибуты и методы от моего OverviewController.

<ui:repeat var="event" value="#{overviewController.eventList}"> 
    ... 
</ui:repeat> 

Все работает нормально, но проблема заключается в файл журнала:

INFO: Enter : RESTORE_VIEW 1 
INFO: Exit : RESTORE_VIEW 1 

INFO: Enter : RENDER_RESPONSE 6 
INFO: => OverviewController - init() - enter 
INFO: => Overview Controller - updateSelectedTab() - enter 
INFO: =< Overview Controller - updateSelectedTab() - exit 
INFO: =< OverviewController - init() - exit 
INFO: => OverviewController - init() - enter 
INFO: => Overview Controller - updateSelectedTab() - enter 
INFO: =< Overview Controller - updateSelectedTab() - exit 
INFO: =< OverviewController - init() - exit 
INFO: Exit : RENDER_RESPONSE 6 

Как вы можете видеть, метод инициализации() вызывается дважды в одной и той же просьбой ни по какой причине, что так когда-либо , Из того, что я знаю, любой метод, аннотированный с помощью , PostConstruct вызывается один раз каждый запрос. Я ошибаюсь?

EDIT: No AJAX используется на странице. Я проверил количество запросов с помощью firebug. Есть запросы дерево из:

  • 1.One для javax.faces.resource (ГЭТ)
  • 2.one для файла CSS (ГЭТ)
  • 3.One для обзора .xhtml (ГЭТ)
+0

ли вы имеете в виду ClassFish или GlassFish? – Kushan

+0

@Kushan GlassFish – Ionut

+0

Выполняете ли вы какие-либо звонки Ajax? Используйте FireBug или подобное дополнение, чтобы узнать, сколько запросов браузер делает. – MrKiane

ответ

19

Это может произойти, если у вас есть несколько структур, распоряжающихся же bean class. Например. JSF и CDI или JSF и Весна или CDI и Весна и т. Д. Дважды проверьте конфигурацию и аннотации на компоненте.

Это также может случиться, если вы используете CDI и используете несколько аннотаций @Named во всем классе. Например, @Named прямо на классе, чтобы зарегистрировать его как управляемый компонент, а другой - для метода getter @Produces. Вам нужно спросить себя, есть ли это действительно необходимо. Вы также можете использовать #{bean.someObject} вместо #{someObject}.

@Named 
@RequestScoped 
public class Bean { 

    @PostConstruct 
    public void init() { 
     // ... 
    } 

    @Named 
    @Produces 
    public SomeObject getSomeObject() { 
     // ... 
    } 

} 

Это также может произойти, если ваш управляемый компонент расширяет некоторый абстрактный класс, который в свою очередь также @PostConstruct по методу. Вы должны удалить аннотацию из него.Кроме того, вы должны сделать метод инициализации аннотации и не имеют @PostConstruct на реализующий бобе:

public abstract class BaseBean { 

    @PostConstruct 
    public void postConstruct() { 
     init(); 
    } 

    public abstract void init(); 

} 
+1

Спасибо! У меня нет нескольких фреймворков, но это помогло мне понять, в чем проблема. Все мои ManagedBeans расширяют «BaseController». У этого BaseController есть метод '@PostConstruct init()', который, как я думал, будет переопределяться с помощью «PostConstruct init()» ManagedBeans. Кажется, что вызываются как 'init()'. Теперь все имеет смысл. Спасибо! – Ionut

+0

Вы не должны иметь '@ PostConstruct' в классе' BaseController'. Убери это. – BalusC

+0

@BalusC: У меня есть небольшой вопрос. Что касается использования JSF и CDI в одном компоненте, если я использую '@ Inject' для вставки компонента CDI в' @ ManagedBean', метод '@ PostConstruct' вызывается дважды? Я не совсем уверен, как применять несколько фреймворков на одном и том же компоненте. Я думал, что структура была решена путем аннотации компонента с '@ ManagedBean',' @ Named' и т. Д. –

3

Вполне возможно, что оба init() способ и @PostConstruct методы стрельбы и вызывая такое поведение. Попробуйте изменить имя метода init() и/или поместить его private. Я думаю, что это может быть связано с вашими проблемами:

http://javahowto.blogspot.com/2011/07/servlet-init-method-vs-postconstruct.html

Я также нашел хороший пост об отладке JSF жизненных циклов здесь: Debug JSF lifecycle

+1

Это не имеет смысла. Управляемый компонент JSF не является реализацией «HttpServlet». – BalusC

+0

Я имел в виду, что в зависимости от конфигурации это может привести к запутанности системы и срабатыванию обоих методов. Возможно, это был длинный выстрел. Спасибо за ваше разъяснение. – MrKiane

+0

Я попытался удалить аннотацию, но тогда init() будет проигнорирован. Поскольку BalusC сказал, что в управляемом компоненте нет метода init(). – Ionut