2013-05-16 3 views
4

Вопрос: как вы измеряете время загрузки страницы, какую технику используете, какие рекомендации вы можете дать, и какой положительный и отрицательный опыт у вас есть.Идеи на измерениях времени загрузки страницы

Проблема в том, что даже легкие страницы в jsf могут занимать до 10 секунд для загрузки. На этих страницах не требуются оценки, ресурсы на рендеринг и т. Д. Очевидный ответ - он находится в очереди на рендеринг ... Хорошо, но может быть что-то еще?

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

У вас есть какая-либо хорошо работающие способы, цепочки инструментов, инструменты для полного времени жизни страницы страницы в JSF?

Glassfish-3, JSF-2 используется. Машина с 64 процессорами.

+0

10 секунд кажется очень длинным, вы можете взглянуть на жизненный цикл JSF в качестве начальной точки: http://balusc.blogspot.ca/2006/09/debug-jsf-lifecycle.html –

+0

@AlexandreLavoie, как вы подумайте (или, может быть, вы знаете), есть ли поддержка из структуры JSF для отслеживания времени? 10 секунд - поскольку показанные страницы нуждаются в информации из баз данных и могут быть мегабайтами размера. Это услуга специального назначения. –

+0

Извините, я не знаю ни инструмента, ни библиотеки, которые могли бы отслеживать статистику времени генерации страниц. Для этого вам необходимо создать PhaseListener и log datetime с URL-адресом. После этого вы сможете отслеживать данные. –

ответ

6

Вот простое пользовательское решение, которое я только что сделал и протестировал. Он предоставляет некоторые статистические данные о времени выполнения и времени выполнения. Конечно, вся информация доступна только с серверной обработки.

пример Результат:

Date      ID request URL         Phase    Execution time 
2013-05-16 21:10:29.781 34   http://localhost:8080/web/page.jspx RESTORE_VIEW 1  15 
2013-05-16 21:10:29.796 34   http://localhost:8080/web/page.jspx RENDER_RESPONSE 6 4438 
2013-05-16 21:10:39.437 35   http://localhost:8080/web/page.jspx RESTORE_VIEW 1  16 
2013-05-16 21:10:39.453 35   http://localhost:8080/web/page.jspx RENDER_RESPONSE 6 3937 

Реализация довольно straigth вперед. Во-первых у вас есть тонна настроить PhaseListener внутри faces-config.xml

<lifecycle> 
    <phase-listener>com.spectotechnologies.jsf.phaselisteners.PhaseProcessesAnalyserListener</phase-listener> 
</lifecycle> 

Вот вспомогательный класс, который хранит информацию о каждой обработке:

package com.spectotechnologies.website.common.helper; 

import java.util.Date; 
import javax.faces.event.PhaseId; 

/** 
* 
* @author Alexandre Lavoie 
*/ 
public class PhaseProcess 
{ 
    private int m_nIDRequest; 
    private String m_sURL; 
    private Date m_oStart; 
    private Date m_oEnd; 
    private PhaseId m_oPhase; 

    public void setIdRequest(int p_nIDRequest) 
    { 
     m_nIDRequest = p_nIDRequest; 
    } 

    public int getIdRequest() 
    { 
     return m_nIDRequest; 
    } 

    public void setUrl(String p_sURL) 
    { 
     m_sURL = p_sURL; 
    } 

    public String getUrl() 
    { 
     return m_sURL; 
    } 

    public void setStart(Date p_oStart) 
    { 
     m_oStart = p_oStart; 
    } 

    public Date getStart() 
    { 
     return m_oStart; 
    } 

    public void setEnd(Date p_oEnd) 
    { 
     m_oEnd = p_oEnd; 
    } 

    public Date getEnd() 
    { 
     return m_oEnd; 
    } 

    public void setPhase(PhaseId p_oPhase) 
    { 
     m_oPhase = p_oPhase; 
    } 

    public PhaseId getPhase() 
    { 
     return m_oPhase; 
    } 

    public long getExecutionTime() 
    { 
     long lExecutionTime = -1; 

     if(getEnd() != null) 
     { 
      lExecutionTime = getEnd().getTime() - getStart().getTime(); 
     } 

     return lExecutionTime; 
    } 
} 

Вот класс с бизнес-логики, примечание что на данный момент статистика будет расти только и никогда не будет удалена, может быть хорошим обновлением, чтобы сохранить только последний час, например:

package com.spectotechnologies.website.common.helper; 

import java.util.ArrayList; 
import java.util.Date; 
import java.util.List; 
import javax.faces.context.FacesContext; 
import javax.faces.event.PhaseId; 

/** 
* 
* @author Alexandre Lavoie 
*/ 
public class PhaseProcesses 
{ 
    private List<PhaseProcess> m_lItems = new ArrayList(); 
    private int m_nNextIDRequest = 0; 

    public static PhaseProcesses getInstance() 
    { 
     FacesContext oFaces = FacesContext.getCurrentInstance(); 

     PhaseProcesses oPhaseProcesses = (PhaseProcesses)oFaces.getExternalContext().getSessionMap().get("sessionPhaseProcesses"); 

     if(oPhaseProcesses == null) 
     { 
      oPhaseProcesses = new PhaseProcesses(); 

      FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("sessionPhaseProcesses",oPhaseProcesses); 
     } 

     return oPhaseProcesses; 
    } 

    public void set(int p_nIDRequest, String p_sURL, PhaseId p_oPhase, int p_nType) 
    { 
     PhaseProcess oPhaseProcess; 

     // Phase start 
     switch(p_nType) 
     { 
      case 0: 
       // start 
       oPhaseProcess = new PhaseProcess(); 

       oPhaseProcess.setIdRequest(p_nIDRequest); 
       oPhaseProcess.setUrl(p_sURL); 
       oPhaseProcess.setPhase(p_oPhase); 
       oPhaseProcess.setStart(new Date()); 

       if(m_lItems.size() > 250) 
      { 
       m_lItems.remove(0); 
      } 

       m_lItems.add(oPhaseProcess); 
       break; 
      case 1: 
       // end 
       for(int nPhase = m_lItems.size() - 1;nPhase >= 0;nPhase--) 
       { 
        if(m_lItems.get(nPhase).getIdRequest() == p_nIDRequest && m_lItems.get(nPhase).getPhase() == p_oPhase) 
        { 
         m_lItems.get(nPhase).setEnd(new Date()); 
         break; 
        } 
       } 
       break; 
     } 
    } 

    public List<PhaseProcess> getList() 
    { 
     return m_lItems; 
    } 

    public Integer getNextIDRequest() 
    { 
     return m_nNextIDRequest++; 
    } 
} 

Здесь находится знаменитый PhaseListener, где информация отслеживаются:

package com.spectotechnologies.jsf.phaselisteners; 

import com.spectotechnologies.website.common.helper.PhaseProcesses; 
import java.net.URLEncoder; 
import java.util.Enumeration; 
import javax.faces.context.FacesContext; 
import javax.faces.event.PhaseEvent; 
import javax.faces.event.PhaseId; 
import javax.faces.event.PhaseListener; 
import javax.servlet.http.HttpServletRequest; 

/** 
* 
* @author Alexandre Lavoie 
*/ 
public class PhaseProcessesAnalyserListener implements PhaseListener 
{ 
    @Override 
    public PhaseId getPhaseId() 
    { 
     return PhaseId.ANY_PHASE; 
    } 

    @Override 
    public void beforePhase(PhaseEvent p_oEvent) 
    { 
     PhaseProcesses.getInstance().set(getIDRequest(),getURL(),p_oEvent.getPhaseId(),0); 
    } 

    @Override 
    public void afterPhase(PhaseEvent p_oEvent) 
    { 
     PhaseProcesses.getInstance().set(getIDRequest(),getURL(),p_oEvent.getPhaseId(),1); 
    } 

    private Integer getIDRequest() 
    { 
     Integer iIDRequest = (Integer)FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get("idrequest"); 

     if(iIDRequest == null) 
     { 
      iIDRequest = PhaseProcesses.getInstance().getNextIDRequest(); 

      FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put("idrequest",iIDRequest); 
     } 

     return iIDRequest; 
    } 

    private String getURL() 
    { 
     Enumeration<String> lParameters; 
     String sParameter; 
     StringBuilder sbURL = new StringBuilder(); 
     Object oRequest = FacesContext.getCurrentInstance().getExternalContext().getRequest(); 

     try 
     { 
      if(oRequest instanceof HttpServletRequest) 
      { 
       sbURL.append(((HttpServletRequest)oRequest).getRequestURL().toString()); 

       lParameters = ((HttpServletRequest)oRequest).getParameterNames(); 

       if(lParameters.hasMoreElements()) 
       { 
        if(!sbURL.toString().contains("?")) 
        { 
         sbURL.append("?"); 
        } 
        else 
        { 
         sbURL.append("&"); 
        } 
       } 

       while(lParameters.hasMoreElements()) 
       { 
        sParameter = lParameters.nextElement(); 

        sbURL.append(sParameter); 
        sbURL.append("="); 
        sbURL.append(URLEncoder.encode(((HttpServletRequest)oRequest).getParameter(sParameter),"UTF-8")); 

        if(lParameters.hasMoreElements()) 
        { 
         sbURL.append("&"); 
        } 
       } 
      } 
     } 
     catch(Exception e) 
     { 
      // Do nothing 
     } 

     return sbURL.toString(); 
    } 
} 

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

Bean Код:

package com.spectotechnologies.website.common.beans; 

import com.spectotechnologies.website.common.helper.PhaseProcess; 
import com.spectotechnologies.website.common.helper.PhaseProcesses; 
import java.util.List; 
import javax.faces.bean.ManagedBean; 
import javax.faces.bean.RequestScoped; 

/** 
* 
* @author Alexandre Lavoie 
*/ 
@ManagedBean 
@RequestScoped 
public class PagesStatisticsActions 
{ 
    public List<PhaseProcess> getList() 
    { 
     return PhaseProcesses.getInstance().getList(); 
    } 
} 

Просмотр кода:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:h="http://java.sun.com/jsf/html" 
    xmlns:f="http://java.sun.com/jsf/core"> 

    <f:view contentType="application/xhtml+xml"> 
     <h:head> 
      <meta http-equiv="Content-Type" content="application/xhtml+xml;charset=UTF-8" /> 
     </h:head> 

     <h:body> 
      <h:dataTable value="#{pagesStatisticsActions.list}" var="item"> 
       <h:column> 
        <f:facet name="header"> 
         Date 
        </f:facet> 

        <h:outputText value="#{item.start}"> 
         <f:convertDateTime timeZone="America/Montreal" pattern="yyyy-MM-dd HH:mm:ss.SSS" /> 
        </h:outputText> 
       </h:column> 

       <h:column> 
        <f:facet name="header"> 
         ID request 
        </f:facet> 

        #{item.idRequest} 
       </h:column> 

       <h:column> 
        <f:facet name="header"> 
         URL 
        </f:facet> 

        #{item.url} 
       </h:column> 

       <h:column> 
        <f:facet name="header"> 
         Phase 
        </f:facet> 

        #{item.phase} 
       </h:column> 

       <h:column> 
        <f:facet name="header"> 
         Execution time (ms) 
        </f:facet> 

        #{item.executionTime} 
       </h:column> 
      </h:dataTable> 
     </h:body> 
    </f:view> 
</html> 

UPDATE 1:

  • Добавлены параметры в URL
  • Добавлено ограничение 250 журналов
+0

Кажется, что полная инструментальная цепочка может быть построена таким образом: вместо измерений времени, поставленных в контексте, мы можем реализовать некоторую службу, которая будет принимать какие-то дейтаграммы (простые сообщения), которые будут принимать уведомления типа { исполнение, идентификатор}. И если мы добавим уведомление с клиентской стороны: http://stackoverflow.com/questions/1211414/page-load-time-with-jquery, если сеть не занята, мы можем оценить, где обрабатывается контент (со стороны данных , или на стороне клиента и т. д.). Я прав? –

+0

Да, это было бы очень приятно, если в конце вычисления jQuery вы можете отправить обратно значение сервлету, например, с помощью PhaseID = Client Rendering или что-то в этом роде. –

+0

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

1

Следующее решение основано на solution разместил Alexandre Lavoie, но применим для ADF Faces:

PhaseProcessingTimeAnalyserListener

import java.io.Serializable; 
import java.net.URLEncoder; 
import java.util.Enumeration; 
import java.util.Map; 
  
import javax.faces.context.FacesContext; 
import javax.servlet.http.HttpServletRequest; 
  
import oracle.adf.controller.v2.lifecycle.Lifecycle; 
import oracle.adf.controller.v2.lifecycle.PagePhaseEvent; 
import oracle.adf.controller.v2.lifecycle.PagePhaseListener; 
import oracle.adf.share.ADFContext; 
  
import com.mhis.posm.web.lifecycle.helper.PhaseProcessor; 
  
/** 
 * Class PhaseProcessingTimeAnalyserListener calculates the execution time of each Phase of ADF 
 * @author TapasB 
 */ 
public class PhaseProcessingTimeAnalyserListener implements PagePhaseListener, Serializable { 
  
 private static final long serialVersionUID = 6814928970314659328L; 
  
 /** 
  * Method beforePhase notifies the listener before the execution of a specific phase of the ADF Page Lifecycle. 
  * @author TapasB 
  * @param phaseEvent 
  * @see oracle.adf.controller.v2.lifecycle.PagePhaseListener#beforePhase(oracle.adf.controller.v2.lifecycle.PagePhaseEvent) 
  */ 
 @Override 
 public void beforePhase(PagePhaseEvent phaseEvent) { 
  int phaseId = phaseEvent.getPhaseId(); 
  String phaseName = Lifecycle.getPhaseName(phaseId); 
  PhaseProcessor.getInstance().process(getRequestId(), getURL(), phaseId, phaseName, PhaseProcessor.PhaseType.BEGIN); 
 } 
  
 /** 
  * Method afterPhase notifies the listener after the execution of a specific phase of the ADF Page Lifecycle. 
  * @author TapasB 
  * @param phaseEvent 
  * @see oracle.adf.controller.v2.lifecycle.PagePhaseListener#afterPhase(oracle.adf.controller.v2.lifecycle.PagePhaseEvent) 
  */ 
 @Override 
 public void afterPhase(PagePhaseEvent phaseEvent) { 
  int phaseId = phaseEvent.getPhaseId(); 
  String phaseName = Lifecycle.getPhaseName(phaseId); 
  PhaseProcessor.getInstance().process(getRequestId(), getURL(), phaseId, phaseName, PhaseProcessor.PhaseType.END); 
 } 
  
 /** 
  * Method getRequestId generates and returns an unique ID value for each Request 
  * @author TapasB 
  * @return requestId 
  */ 
 private Integer getRequestId() { 
  @SuppressWarnings("unchecked") 
  Map<String, Object> requestScope = ADFContext.getCurrent().getRequestScope(); 
  Integer requestId = (Integer) requestScope.get("requestId"); 
  
  if (requestId == null) { 
   requestId = PhaseProcessor.getInstance().getNextRequestId(); 
   requestScope.put("requestId", requestId); 
  } 
  
  return requestId; 
 } 
  
 /** 
  * Method getURL returns the URL in which the application is requested 
  * @author TapasB 
  * @return a String URL 
  */ 
 private String getURL() { 
  Enumeration<String> parameterNames = null; 
  String parameterName = null; 
  StringBuilder urlBuilder = new StringBuilder(); 
  Object request = FacesContext.getCurrentInstance().getExternalContext().getRequest(); 
  
  try { 
   if (request instanceof HttpServletRequest) { 
    HttpServletRequest servletRequest = (HttpServletRequest) request; 
    urlBuilder.append(servletRequest.getRequestURL().toString()); 
    parameterNames = servletRequest.getParameterNames(); 
  
    if (parameterNames.hasMoreElements()) { 
     if (!urlBuilder.toString().contains("?")) { 
      urlBuilder.append("?"); 
     } else { 
      urlBuilder.append("&"); 
     } 
    } 
  
    while (parameterNames.hasMoreElements()) { 
     parameterName = parameterNames.nextElement(); 
  
     urlBuilder.append(parameterName); 
     urlBuilder.append("="); 
     urlBuilder.append(URLEncoder.encode(servletRequest.getParameter(parameterName), "UTF-8")); 
  
     if (parameterNames.hasMoreElements()) { 
      urlBuilder.append("&"); 
     } 
    } 
   } 
  } catch (Exception ex) { 
  } 
  
  return urlBuilder.toString(); 
 } 
} 

PhaseProcessor

import java.io.Serializable; 
import java.util.ArrayList; 
import java.util.Date; 
import java.util.List; 
import java.util.ListIterator; 
import java.util.Map; 
import java.util.concurrent.atomic.AtomicInteger; 
  
import oracle.adf.share.ADFContext; 
  
import com.edifixio.osrd.generic.log.Log; 
  
/** 
 * Class PhaseProcessor processes the Phase execution time 
 * @author TapasB 
 */ 
public class PhaseProcessor implements Serializable { 
  
 private static final long serialVersionUID = 6658181867505616109L; 
  
 private List<Phase> phases = new ArrayList<Phase>(); 
 private AtomicInteger nextRequestId = new AtomicInteger(1); 
  
 /** 
  * Constructor PhaseProcessor is private 
  * @author TapasB 
  */ 
 private PhaseProcessor() { 
  
 } 
  
 /** 
  * Class PhaseType 
  * @author TapasB 
  */ 
 public static enum PhaseType { 
  BEGIN, 
  END; 
 } 
  
 /** 
  * Method getInstance returns a Session Instance of this class 
  * @author TapasB 
  * @return an PhaseProcessor instance 
  */ 
 public static PhaseProcessor getInstance() { 
  @SuppressWarnings("unchecked") 
  Map<String, Object> sessionScope = ADFContext.getCurrent().getSessionScope(); 
  PhaseProcessor phaseProcessor = (PhaseProcessor) sessionScope.get("phases"); 
  
  if (phaseProcessor == null) { 
   phaseProcessor = new PhaseProcessor(); 
   sessionScope.put("phases", phaseProcessor); 
  } 
  
  return phaseProcessor; 
 } 
  
 /** 
  * Method process processes the {@link Phase} 
  * @author TapasB 
  * @param requestId - the unique ID for each request 
  * @param url - the url in which the application is requested 
  * @param phaseId - ADF's Phase ID 
  * @param phaseName - ADF's Phase Name 
  * @param phaseType - BEGIN or END 
  */ 
 public void process(int requestId, String url, int phaseId, String phaseName, PhaseType phaseType) { 
  Phase phase; 
  
  switch (phaseType) { 
   case BEGIN: 
    phase = new Phase(); 
  
    phase.setRequestId(requestId); 
    phase.setUrl(url); 
    phase.setPhaseId(phaseId); 
    phase.setPhaseName(phaseName); 
    phase.setStartTime(new Date()); 
  
    phases.add(phase); 
  
    Log.info(this, "The Phase: " + phase.getPhaseName(phaseId) + " begins. Requested URL: " + phase.getUrl()); 
    break; 
  
   case END: 
    ListIterator<Phase> phaseIterator = phases.listIterator(phases.size()); 
  
    while (phaseIterator.hasPrevious()) { 
     phase = phaseIterator.previous(); 
  
     if (phase.getRequestId() == requestId && phase.getPhaseId() == phaseId && phase.getPhaseName().equals(phaseName)) { 
      phase.setEndTime(new Date()); 
      Log.info(this, "The Phase: " + phase.getPhaseName(phaseId) + " ends with execution time: '" + (phase.getEndTime().getTime() - phase.getStartTime().getTime()) + "' millisecondes. Requested URL: " + phase.getUrl()); 
      phaseIterator.remove(); 
      break; 
     } 
  
    } 
  
    break; 
  } 
 } 
  
 /** 
  * Method getNextRequestId returns and increment the unique ID 
  * @author TapasB 
  * @return the ID 
  */ 
 public Integer getNextRequestId() { 
  return nextRequestId.getAndIncrement(); 
 } 
} 

Фаза

import java.io.Serializable; 
import java.util.Date; 
  
import oracle.adf.controller.faces.lifecycle.JSFLifecycle; 
  
/** 
 * Class Phase represent a phase 
 * @author TapasB 
 */ 
public class Phase implements Serializable { 
  
 private static final long serialVersionUID = -461595462579265128L; 
  
 private int requestId; 
 private String url; 
 private Date startTime; 
 private Date endTime; 
 private int phaseId; 
 private String phaseName; 
  
 /** 
  * Constructor Phase is default 
  * @author TapasB 
  */ 
 public Phase() { 
  
 } 
  
 /** 
  * Method getRequestId returns requestId 
  * @author TapasB 
  * @return requestId 
  */ 
 public int getRequestId() { 
  return requestId; 
 } 
  
 /** 
  * Method setRequestId sets the requestId 
  * @author TapasB 
  * @param requestId the requestId to set 
  */ 
 public void setRequestId(int requestId) { 
  this.requestId = requestId; 
 } 
  
 /** 
  * Method getUrl returns url 
  * @author TapasB 
  * @return url 
  */ 
 public String getUrl() { 
  return url; 
 } 
  
 /** 
  * Method setUrl sets the url 
  * @author TapasB 
  * @param url the url to set 
  */ 
 public void setUrl(String url) { 
  this.url = url; 
 } 
  
 /** 
  * Method getStartTime returns startTime 
  * @author TapasB 
  * @return startTime 
  */ 
 public Date getStartTime() { 
  return startTime; 
 } 
  
 /** 
  * Method setStartTime sets the startTime 
  * @author TapasB 
  * @param startTime the startTime to set 
  */ 
 public void setStartTime(Date startTime) { 
  this.startTime = startTime; 
 } 
  
 /** 
  * Method getEndTime returns endTime 
  * @author TapasB 
  * @return endTime 
  */ 
 public Date getEndTime() { 
  return endTime; 
 } 
  
 /** 
  * Method setEndTime sets the endTime 
  * @author TapasB 
  * @param endTime the endTime to set 
  */ 
 public void setEndTime(Date endTime) { 
  this.endTime = endTime; 
 } 
  
 /** 
  * Method getPhaseId returns phaseId 
  * @author TapasB 
  * @return phaseId 
  */ 
 public int getPhaseId() { 
  return phaseId; 
 } 
  
 /** 
  * Method setPhaseId sets the phaseId 
  * @author TapasB 
  * @param phaseId the phaseId to set 
  */ 
 public void setPhaseId(int phaseId) { 
  this.phaseId = phaseId; 
 } 
  
 /** 
  * Method getPhaseName returns phaseName 
  * @author TapasB 
  * @return phaseName 
  */ 
 public String getPhaseName() { 
  return phaseName; 
 } 
  
 /** 
  * Method setPhaseName sets the phaseName 
  * @author TapasB 
  * @param phaseName the phaseName to set 
  */ 
 public void setPhaseName(String phaseName) { 
  this.phaseName = phaseName; 
 } 
  
 /** 
  * Method getPhaseName returns the name of the Phase 
  * @author TapasB 
  * @param phaseId 
  * @return the phase name 
  */ 
 public String getPhaseName(int phaseId) { 
  if (phaseId == JSFLifecycle.INIT_CONTEXT_ID) { 
   return "INIT_CONTEXT"; 
  } else if (phaseId == JSFLifecycle.PREPARE_MODEL_ID) { 
   return "PREPARE_MODEL"; 
  } else if (phaseId == JSFLifecycle.APPLY_INPUT_VALUES_ID) { 
   return "APPLY_INPUT_VALUES"; 
  } else if (phaseId == JSFLifecycle.VALIDATE_INPUT_VALUES_ID) { 
   return "VALIDATE_INPUT_VALUES"; 
  } else if (phaseId == JSFLifecycle.PROCESS_UPDATE_MODEL_ID) { 
   return "PROCESS_UPDATE_MODEL"; 
  } else if (phaseId == JSFLifecycle.VALIDATE_MODEL_UPDATES_ID) { 
   return "VALIDATE_MODEL_UPDATES"; 
  } else if (phaseId == JSFLifecycle.PROCESS_COMPONENT_EVENTS_ID) { 
   return "PROCESS_COMPONENT_EVENTS"; 
  } else if (phaseId == JSFLifecycle.METADATA_COMMIT_ID) { 
   return "METADATA_COMMIT"; 
  } else if (phaseId == JSFLifecycle.PREPARE_RENDER_ID) { 
   return "PREPARE_RENDER"; 
  } else if (phaseId == JSFLifecycle.JSF_RESTORE_VIEW_ID) { 
   return "RESTORE_VIEW"; 
  } else if (phaseId == JSFLifecycle.JSF_APPLY_REQUEST_VALUES_ID) { 
   return "JSF_APPLY_REQUEST_VALUES"; 
  } else if (phaseId == JSFLifecycle.JSF_PROCESS_VALIDATIONS_ID) { 
   return "JSF_PROCESS_VALIDATIONS"; 
  } else if (phaseId == JSFLifecycle.JSF_UPDATE_MODEL_VALUES_ID) { 
   return "JSF_UPDATE_MODEL_VALUES"; 
  } else if (phaseId == JSFLifecycle.JSF_INVOKE_APPLICATION_ID) { 
   return "JSF_INVOKE_APPLICATION"; 
  } else { 
   return "JSF_RENDER_RESPONSE"; 
  } 
 } 
} 

Для получения дополнительной информации смотрите here.

Смежные вопросы